Skip to content

Commit

Permalink
Add Route overview button
Browse files Browse the repository at this point in the history
  • Loading branch information
danesfeder committed Jun 8, 2018
1 parent 69e69e8 commit c6c9676
Show file tree
Hide file tree
Showing 35 changed files with 634 additions and 219 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,6 @@ interface View {

void addMarker(Point point);

void finishNavigationView();

void takeScreenshot();

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

boolean isRecenterButtonVisible();

void updateCameraRouteOverview();

void updateWaynameVisibility(boolean isVisible);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,13 +23,10 @@ void onRecenterClick() {
view.setSummaryBehaviorHideable(false);
view.setSummaryBehaviorState(BottomSheetBehavior.STATE_EXPANDED);
view.resetCameraPosition();
view.updateWaynameVisibility(true);
view.hideRecenterBtn();
}

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

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

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

public void onInstructionListVisibilityChanged(boolean visible) {
void onInstructionListVisibilityChanged(boolean visible) {
if (visible) {
view.hideRecenterBtn();
} else {
view.showRecenterBtn();
}
}

void onRouteOverviewClick() {
view.updateWaynameVisibility(false);
view.updateCameraRouteOverview();
view.showRecenterBtn();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@
import com.mapbox.services.android.navigation.v5.navigation.NavigationTimeFormat;
import com.mapbox.services.android.navigation.v5.utils.LocaleUtils;

import static com.mapbox.services.android.navigation.ui.v5.utils.ViewUtils.buildRouteOverviewPadding;

/**
* View that creates the drop-in UI.
* <p>
Expand Down Expand Up @@ -68,6 +70,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 @@ -272,6 +275,7 @@ public void updateWaynameView(String wayname) {
navigationMap.updateWaynameView(wayname);
}

@Override
public void updateWaynameVisibility(boolean isVisible) {
navigationMap.updateWaynameVisibility(isVisible);
}
Expand All @@ -280,15 +284,6 @@ 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() {
Expand Down Expand Up @@ -330,6 +325,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 @@ -390,6 +391,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 Down Expand Up @@ -471,17 +473,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 @@ -499,7 +490,6 @@ private void initializeListeners() {
cancelBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
navigationPresenter.onCancelBtnClick();
navigationViewEventDispatcher.onCancelNavigation();
}
});
Expand All @@ -509,6 +499,12 @@ public void onClick(View view) {
navigationPresenter.onRecenterClick();
}
});
routeOverviewBtn.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View view) {
navigationPresenter.onRouteOverviewClick();
}
});
}

private void establish(NavigationViewOptions options) {
Expand Down Expand Up @@ -548,7 +544,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
Expand Up @@ -62,6 +62,17 @@ public static int retrieveNavigationViewStyle(Context context, int styleResId) {
return outValue.resourceId;
}

/**
* Returns true if the current UI_MODE_NIGHT is enabled, false otherwise.
*
* @param context to retrieve the current configuration
*/
public static boolean isDarkThemeEnabled(Context context) {
int uiMode = context.getResources().getConfiguration().uiMode
& Configuration.UI_MODE_NIGHT_MASK;
return uiMode == Configuration.UI_MODE_NIGHT_YES;
}

/**
* Called in onCreate() to check the UI Mode (day or night)
* and set the theme colors accordingly.
Expand All @@ -70,17 +81,15 @@ public static int retrieveNavigationViewStyle(Context context, int styleResId) {
* @param attrs holding custom styles if any are set
*/
static void setTheme(Context context, AttributeSet attrs) {
int uiMode = context.getResources().getConfiguration().uiMode
& Configuration.UI_MODE_NIGHT_MASK;
boolean darkThemeEnabled = uiMode == Configuration.UI_MODE_NIGHT_YES;
boolean darkThemeEnabled = isDarkThemeEnabled(context);
updatePreferencesDarkEnabled(context, darkThemeEnabled);

// Check for custom theme from NavigationLauncher
if (shouldSetThemeFromPreferences(context)) {
int prefLightTheme = retrieveThemeResIdFromPreferences(context, NavigationConstants.NAVIGATION_VIEW_LIGHT_THEME);
int prefDarkTheme = retrieveThemeResIdFromPreferences(context, NavigationConstants.NAVIGATION_VIEW_DARK_THEME);
prefLightTheme = prefLightTheme == 0 ? R.style.NavigationViewLight : prefLightTheme;
prefDarkTheme = prefLightTheme == 0 ? R.style.NavigationViewDark : prefDarkTheme;
prefLightTheme = prefLightTheme == 0 ? R.style.NavigationViewLight : prefLightTheme;
prefDarkTheme = prefLightTheme == 0 ? R.style.NavigationViewDark : prefDarkTheme;
context.setTheme(darkThemeEnabled ? prefDarkTheme : prefLightTheme);
return;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,8 +60,7 @@ public double tilt(RouteInformation routeInformation) {

@Override
public double zoom(RouteInformation routeInformation) {
RouteInformation information = routeInformation;
if (validLocationAndProgress(information) && shouldUpdateZoom(information)) {
if (validLocationAndProgress(routeInformation) && shouldUpdateZoom(routeInformation)) {
return createZoom(routeInformation);
} else if (routeInformation.route() != null) {
return super.zoom(routeInformation);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,20 @@
import com.mapbox.api.directions.v5.models.DirectionsRoute;
import com.mapbox.geojson.Point;
import com.mapbox.mapboxsdk.camera.CameraPosition;
import com.mapbox.mapboxsdk.camera.CameraUpdate;
import com.mapbox.mapboxsdk.camera.CameraUpdateFactory;
import com.mapbox.mapboxsdk.geometry.LatLng;
import com.mapbox.mapboxsdk.geometry.LatLngBounds;
import com.mapbox.mapboxsdk.maps.MapboxMap;
import com.mapbox.services.android.navigation.v5.navigation.MapboxNavigation;
import com.mapbox.services.android.navigation.v5.navigation.camera.Camera;
import com.mapbox.services.android.navigation.v5.navigation.camera.RouteInformation;
import com.mapbox.services.android.navigation.v5.routeprogress.ProgressChangeListener;
import com.mapbox.services.android.navigation.v5.routeprogress.RouteProgress;

import java.util.ArrayList;
import java.util.List;

/**
* Updates the map camera while navigating.
* <p>
Expand All @@ -35,11 +40,13 @@ public class NavigationCamera implements LifecycleObserver {
private MapboxMap mapboxMap;
private MapboxNavigation navigation;
private RouteInformation currentRouteInformation;
private RouteProgress currentRouteProgress;
private boolean trackingEnabled = true;
private long locationUpdateTimestamp;
private ProgressChangeListener progressChangeListener = new ProgressChangeListener() {
@Override
public void onProgressChange(Location location, RouteProgress routeProgress) {
currentRouteProgress = routeProgress;
if (trackingEnabled) {
currentRouteInformation = buildRouteInformationFromLocation(location, routeProgress);
animateCameraFromLocation(currentRouteInformation);
Expand Down Expand Up @@ -134,7 +141,7 @@ public boolean isTrackingEnabled() {
* @since 0.6.0
*/
public void resetCameraPosition() {
this.trackingEnabled = true;
trackingEnabled = true;
if (currentRouteInformation != null) {
if (navigation.getCameraEngine() instanceof DynamicCamera) {
((DynamicCamera) navigation.getCameraEngine()).forceResetZoomLevel();
Expand All @@ -143,6 +150,12 @@ public void resetCameraPosition() {
}
}

public void showRouteOverview(int[] padding) {
trackingEnabled = false;
RouteInformation routeInformation = buildRouteInformationFromRouteProgress(currentRouteProgress);
animateCameraForRouteOverview(routeInformation, padding);
}

/**
* Call in {@link FragmentActivity#onDestroy()} to properly remove the {@link ProgressChangeListener}
* for the camera and prevent any leaks or further updates.
Expand Down Expand Up @@ -187,6 +200,14 @@ private RouteInformation buildRouteInformationFromLocation(Location location, Ro
return RouteInformation.create(null, location, routeProgress);
}

@NonNull
private RouteInformation buildRouteInformationFromRouteProgress(RouteProgress routeProgress) {
if (routeProgress != null) {
return RouteInformation.create(routeProgress.directionsRoute(), null, null);
}
return RouteInformation.create(null, null, null);
}

/**
* Will animate the {@link MapboxMap} to the given {@link CameraPosition} with the given duration.
*
Expand Down Expand Up @@ -246,6 +267,45 @@ public void onFinish() {
});
}

private void animateCameraForRouteOverview(RouteInformation routeInformation, int[] padding) {
Camera cameraEngine = navigation.getCameraEngine();

CameraPosition resetPosition = new CameraPosition.Builder().tilt(0).bearing(0).build();
CameraUpdate resetUpdate = CameraUpdateFactory.newCameraPosition(resetPosition);

List<Point> routePoints = cameraEngine.overview(routeInformation);
boolean invalidPoints = routePoints.isEmpty();
if (invalidPoints) {
return;
}
final LatLngBounds routeBounds = convertRoutePointsToLatLngBounds(routePoints);
final CameraUpdate overviewUpdate = CameraUpdateFactory.newLatLngBounds(
routeBounds, padding[0], padding[1], padding[2], padding[3]
);

mapboxMap.animateCamera(resetUpdate, 150, new MapboxMap.CancelableCallback() {
@Override
public void onCancel() {
// No-op
}

@Override
public void onFinish() {
mapboxMap.animateCamera(overviewUpdate, 750);
}
});
}

private LatLngBounds convertRoutePointsToLatLngBounds(List<Point> routePoints) {
List<LatLng> latLngs = new ArrayList<>();
for (Point routePoint : routePoints) {
latLngs.add(new LatLng(routePoint.latitude(), routePoint.longitude()));
}
return new LatLngBounds.Builder()
.includes(latLngs)
.build();
}

/**
* Creates an animation with the given {@link RouteInformation#location()}.
* <p>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
package com.mapbox.services.android.navigation.ui.v5.map;

import android.content.Context;
import android.content.res.Resources;

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

class MapPaddingAdjustor {

private static final int[] ZERO_MAP_PADDING = {0, 0, 0, 0};
private static final int BOTTOMSHEET_PADDING_MULTIPLIER = 4;
private static final int WAYNAME_PADDING_MULTIPLIER = 2;

private final int defaultTopPadding;
private final int waynameTopPadding;
private MapboxMap mapboxMap;

MapPaddingAdjustor(MapView mapView, MapboxMap mapboxMap) {
this.mapboxMap = mapboxMap;
defaultTopPadding = calculateTopPaddingDefault(mapView);
waynameTopPadding = calculateTopPaddingWithWayname(mapView.getContext(), defaultTopPadding);
}

void updateTopPaddingWithWayname() {
updateTopPadding(waynameTopPadding);
}

void updateTopPaddingWithDefault() {
updateTopPadding(defaultTopPadding);
}

void removeAllPadding() {
updatePadding(ZERO_MAP_PADDING);
}

private int calculateTopPaddingDefault(MapView mapView) {
Context context = mapView.getContext();
Resources resources = context.getResources();
int mapViewHeight = mapView.getHeight();
int bottomSheetHeight = (int) resources.getDimension(R.dimen.summary_bottomsheet_height);
return mapViewHeight - (bottomSheetHeight * BOTTOMSHEET_PADDING_MULTIPLIER);
}

private int calculateTopPaddingWithWayname(Context context, int defaultTopPadding) {
Resources resources = context.getResources();
int waynameLayoutHeight = (int) resources.getDimension(R.dimen.wayname_view_height);
return defaultTopPadding - (waynameLayoutHeight * WAYNAME_PADDING_MULTIPLIER);
}

private void updatePadding(int[] padding) {
mapboxMap.setPadding(padding[0], padding[1], padding[2], padding[3]);
}

private void updateTopPadding(int topPadding) {
mapboxMap.setPadding(0, topPadding, 0, 0);
}
}
Loading

0 comments on commit c6c9676

Please sign in to comment.