Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add route overview button and animation to NavigationView #967

Merged
merged 1 commit into from
Jun 19, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package com.mapbox.services.android.navigation.ui.v5;

import android.view.View;

class CancelBtnClickListener implements View.OnClickListener {

private NavigationViewEventDispatcher dispatcher;

CancelBtnClickListener(NavigationViewEventDispatcher dispatcher) {
this.dispatcher = dispatcher;
}

@Override
public void onClick(View view) {
dispatcher.onCancelNavigation();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,6 @@ interface View {

void addMarker(Point point);

void finishNavigationView();

void takeScreenshot();

void startCamera(DirectionsRoute directionsRoute);
Expand All @@ -40,5 +38,7 @@ interface View {
void updateNavigationMap(Location location);

boolean isRecenterButtonVisible();

void updateCameraRouteOverview();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package com.mapbox.services.android.navigation.ui.v5;

import com.mapbox.services.android.navigation.ui.v5.listeners.InstructionListListener;

class NavigationInstructionListListener implements InstructionListListener {

private NavigationPresenter presenter;
private NavigationViewEventDispatcher dispatcher;

NavigationInstructionListListener(NavigationPresenter presenter, NavigationViewEventDispatcher dispatcher) {
this.presenter = presenter;
this.dispatcher = dispatcher;
}

@Override
public void onInstructionListVisibilityChanged(boolean visible) {
presenter.onInstructionListVisibilityChanged(visible);
dispatcher.onInstructionListVisibilityChanged(visible);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,6 @@ void onRecenterClick() {
view.hideRecenterBtn();
}

void onCancelBtnClick() {
view.finishNavigationView();
}

void onMapScroll() {
if (!view.isSummaryBottomSheetHidden()) {
view.setSummaryBehaviorHideable(true);
Expand All @@ -48,6 +44,7 @@ void onSummaryBottomSheetHidden() {

void onRouteUpdate(DirectionsRoute directionsRoute) {
view.drawRoute(directionsRoute);
view.updateWaynameVisibility(true);
if (!resumeState) {
view.startCamera(directionsRoute);
}
Expand All @@ -69,7 +66,7 @@ void onNavigationLocationUpdate(Location location) {
view.updateNavigationMap(location);
}

public void onInstructionListVisibilityChanged(boolean visible) {
void onInstructionListVisibilityChanged(boolean visible) {
if (visible) {
view.hideRecenterBtn();
} else {
Expand All @@ -78,4 +75,10 @@ public void onInstructionListVisibilityChanged(boolean visible) {
}
}
}

void onRouteOverviewClick() {
view.updateWaynameVisibility(false);
view.updateCameraRouteOverview();
view.showRecenterBtn();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
package com.mapbox.services.android.navigation.ui.v5;

import android.graphics.Bitmap;
import android.support.annotation.NonNull;
import android.view.View;
import android.widget.ImageView;

import com.mapbox.mapboxsdk.maps.MapView;
import com.mapbox.mapboxsdk.maps.MapboxMap;
import com.mapbox.services.android.navigation.ui.v5.utils.ViewUtils;

class NavigationSnapshotReadyCallback implements MapboxMap.SnapshotReadyCallback {

private NavigationView navigationView;
private NavigationViewModel navigationViewModel;

NavigationSnapshotReadyCallback(NavigationView navigationView, NavigationViewModel navigationViewModel) {
this.navigationView = navigationView;
this.navigationViewModel = navigationViewModel;
}

@Override
public void onSnapshotReady(Bitmap snapshot) {
ImageView screenshotView = updateScreenshotViewWithSnapshot(snapshot);
updateFeedbackScreenshot();
resetViewVisibility(screenshotView);
}

@NonNull
private ImageView updateScreenshotViewWithSnapshot(Bitmap snapshot) {
ImageView screenshotView = navigationView.findViewById(R.id.screenshotView);
screenshotView.setVisibility(View.VISIBLE);
screenshotView.setImageBitmap(snapshot);
return screenshotView;
}

private void updateFeedbackScreenshot() {
MapView mapView = navigationView.findViewById(R.id.mapView);
mapView.setVisibility(View.INVISIBLE);
Bitmap capture = ViewUtils.captureView(mapView);
String encoded = ViewUtils.encodeView(capture);
navigationViewModel.updateFeedbackScreenshot(encoded);
}

private void resetViewVisibility(ImageView screenshotView) {
screenshotView.setVisibility(View.INVISIBLE);
MapView mapView = navigationView.findViewById(R.id.mapView);
mapView.setVisibility(View.VISIBLE);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,9 @@
import android.arch.lifecycle.LifecycleOwner;
import android.arch.lifecycle.ViewModelProviders;
import android.content.Context;
import android.graphics.Bitmap;
import android.content.res.Resources;
import android.location.Location;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.design.widget.BottomSheetBehavior;
import android.support.design.widget.CoordinatorLayout;
Expand All @@ -18,7 +17,6 @@
import android.util.AttributeSet;
import android.view.View;
import android.widget.ImageButton;
import android.widget.ImageView;

import com.mapbox.api.directions.v5.models.DirectionsRoute;
import com.mapbox.geojson.Point;
Expand All @@ -27,10 +25,8 @@
import com.mapbox.mapboxsdk.maps.OnMapReadyCallback;
import com.mapbox.services.android.navigation.ui.v5.instruction.ImageCoordinator;
import com.mapbox.services.android.navigation.ui.v5.instruction.InstructionView;
import com.mapbox.services.android.navigation.ui.v5.listeners.InstructionListListener;
import com.mapbox.services.android.navigation.ui.v5.map.NavigationMapboxMap;
import com.mapbox.services.android.navigation.ui.v5.summary.SummaryBottomSheet;
import com.mapbox.services.android.navigation.ui.v5.utils.ViewUtils;
import com.mapbox.services.android.navigation.v5.location.MockLocationEngine;
import com.mapbox.services.android.navigation.v5.navigation.MapboxNavigation;
import com.mapbox.services.android.navigation.v5.navigation.NavigationRoute;
Expand Down Expand Up @@ -68,6 +64,7 @@ public class NavigationView extends CoordinatorLayout implements LifecycleObserv
private BottomSheetBehavior summaryBehavior;
private ImageButton cancelBtn;
private RecenterButton recenterBtn;
private ImageButton routeOverviewBtn;

private NavigationPresenter navigationPresenter;
private NavigationViewEventDispatcher navigationViewEventDispatcher;
Expand Down Expand Up @@ -282,25 +279,9 @@ public void updateWaynameQueryMap(boolean isEnabled) {
navigationMap.updateWaynameQueryMap(isEnabled);
}

/**
* Called when the navigation session is finished.
* Can either be from a cancel event or if the user has arrived at their destination.
*/
@Override
public void finishNavigationView() {
navigationViewEventDispatcher.onNavigationFinished();
}

@Override
public void takeScreenshot() {
map.snapshot(new MapboxMap.SnapshotReadyCallback() {
@Override
public void onSnapshotReady(Bitmap snapshot) {
ImageView screenshotView = updateScreenshotViewWithSnapshot(snapshot);
updateFeedbackScreenshot();
resetViewVisibility(screenshotView);
}
});
map.snapshot(new NavigationSnapshotReadyCallback(this, navigationViewModel));
}

/**
Expand Down Expand Up @@ -332,6 +313,12 @@ public void updateNavigationMap(Location location) {
navigationMap.updateLocation(location);
}

@Override
public void updateCameraRouteOverview() {
int[] padding = buildRouteOverviewPadding(getContext());
navigationMap.showRouteOverview(padding);
}

/**
* Should be called when this view is completely initialized.
*
Expand Down Expand Up @@ -380,10 +367,10 @@ private void initializeView() {
inflate(getContext(), R.layout.navigation_view_layout, this);
bind();
initializeNavigationViewModel();
initializeSummaryBottomSheet();
initializeNavigationEventDispatcher();
initializeNavigationPresenter();
initializeInstructionListListener();
initializeSummaryBottomSheet();
}

private void bind() {
Expand All @@ -392,6 +379,7 @@ private void bind() {
summaryBottomSheet = findViewById(R.id.summaryBottomSheet);
cancelBtn = findViewById(R.id.cancelBtn);
recenterBtn = findViewById(R.id.recenterBtn);
routeOverviewBtn = findViewById(R.id.routeOverviewBtn);
}

private void initializeNavigationViewModel() {
Expand All @@ -405,17 +393,8 @@ private void initializeNavigationViewModel() {
private void initializeSummaryBottomSheet() {
summaryBehavior = BottomSheetBehavior.from(summaryBottomSheet);
summaryBehavior.setHideable(false);
summaryBehavior.setBottomSheetCallback(new BottomSheetBehavior.BottomSheetCallback() {
@Override
public void onStateChanged(@NonNull View bottomSheet, int newState) {
navigationViewEventDispatcher.onBottomSheetStateChanged(bottomSheet, newState);
navigationPresenter.onSummaryBottomSheetHidden();
}

@Override
public void onSlide(@NonNull View bottomSheet, float slideOffset) {
}
});
summaryBehavior.setBottomSheetCallback(new SummaryBottomSheetCallback(navigationPresenter,
navigationViewEventDispatcher));
}

private void initializeNavigationEventDispatcher() {
Expand All @@ -424,13 +403,8 @@ private void initializeNavigationEventDispatcher() {
}

private void initializeInstructionListListener() {
instructionView.setInstructionListListener(new InstructionListListener() {
@Override
public void onInstructionListVisibilityChanged(boolean visible) {
navigationPresenter.onInstructionListVisibilityChanged(visible);
navigationViewEventDispatcher.onInstructionListVisibilityChanged(visible);
}
});
instructionView.setInstructionListListener(new NavigationInstructionListListener(navigationPresenter,
navigationViewEventDispatcher));
}

/**
Expand All @@ -445,24 +419,13 @@ private void resetBottomSheetState(int bottomSheetState) {
summaryBehavior.setState(bottomSheetState);
}

@NonNull
private ImageView updateScreenshotViewWithSnapshot(Bitmap snapshot) {
ImageView screenshotView = findViewById(R.id.screenshotView);
screenshotView.setVisibility(View.VISIBLE);
screenshotView.setImageBitmap(snapshot);
return screenshotView;
}

private void updateFeedbackScreenshot() {
mapView.setVisibility(View.INVISIBLE);
Bitmap capture = ViewUtils.captureView(mapView);
String encoded = ViewUtils.encodeView(capture);
navigationViewModel.updateFeedbackScreenshot(encoded);
}

private void resetViewVisibility(ImageView screenshotView) {
screenshotView.setVisibility(View.INVISIBLE);
mapView.setVisibility(View.VISIBLE);
private int[] buildRouteOverviewPadding(Context context) {
Resources resources = context.getResources();
int leftRightPadding = (int) resources.getDimension(R.dimen.route_overview_left_right_padding);
int paddingBuffer = (int) resources.getDimension(R.dimen.route_overview_buffer_padding);
int instructionHeight = (int) (resources.getDimension(R.dimen.instruction_layout_height) + paddingBuffer);
int summaryHeight = (int) resources.getDimension(R.dimen.summary_bottomsheet_height);
return new int[] {leftRightPadding, instructionHeight, leftRightPadding, summaryHeight};
}

private boolean isChangingConfigurations() {
Expand All @@ -473,17 +436,6 @@ private boolean isChangingConfigurations() {
}
}

/**
* Create a top map padding value that pushes the focal point
* of the map to the bottom of the screen (above the bottom sheet).
*/
private int createDefaultMapTopPadding() {
int mapViewHeight = mapView.getHeight();
int bottomSheetHeight = summaryBottomSheet.getHeight();
return mapViewHeight - (bottomSheetHeight * 4);
}


private void initializeNavigationPresenter() {
navigationPresenter = new NavigationPresenter(this);
}
Expand All @@ -498,19 +450,9 @@ private void updatePresenterState(@Nullable Bundle savedInstanceState) {

private void initializeListeners() {
map.addOnScrollListener(NavigationView.this);
cancelBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
navigationPresenter.onCancelBtnClick();
navigationViewEventDispatcher.onCancelNavigation();
}
});
recenterBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
navigationPresenter.onRecenterClick();
}
});
cancelBtn.setOnClickListener(new CancelBtnClickListener(navigationViewEventDispatcher));
recenterBtn.setOnClickListener(new RecenterBtnClickListener(navigationPresenter));
routeOverviewBtn.setOnClickListener(new RouteOverviewBtnClickListener(navigationPresenter));
}

private void establish(NavigationViewOptions options) {
Expand Down Expand Up @@ -550,7 +492,6 @@ private void initializeNavigationListeners(NavigationViewOptions options, Mapbox

private void initializeNavigationMapboxMap(NavigationViewOptions options, MapboxNavigation navigation) {
navigationMap = new NavigationMapboxMap(mapView, map, navigation);
navigationMap.updateDefaultMapTopPadding(createDefaultMapTopPadding());
navigationMap.updateWaynameQueryMap(options.waynameChipEnabled());
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package com.mapbox.services.android.navigation.ui.v5;

import android.view.View;

class RecenterBtnClickListener implements View.OnClickListener {

private NavigationPresenter presenter;

RecenterBtnClickListener(NavigationPresenter presenter) {
this.presenter = presenter;
}

@Override
public void onClick(View view) {
presenter.onRecenterClick();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package com.mapbox.services.android.navigation.ui.v5;

import android.view.View;

class RouteOverviewBtnClickListener implements View.OnClickListener {

private NavigationPresenter presenter;

RouteOverviewBtnClickListener(NavigationPresenter presenter) {
this.presenter = presenter;
}

@Override
public void onClick(View view) {
presenter.onRouteOverviewClick();
}
}
Loading