Skip to content

Commit

Permalink
add 12/24 hour format navigation view option
Browse files Browse the repository at this point in the history
  • Loading branch information
Guardiola31337 committed Mar 28, 2018
1 parent 2975aea commit d4cd5da
Show file tree
Hide file tree
Showing 13 changed files with 464 additions and 195 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package com.mapbox.services.android.navigation.ui.v5;

import android.support.annotation.IntDef;

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;

public class NavigationTimeFormat {

@Retention(RetentionPolicy.SOURCE)
@IntDef( {NONE_SPECIFIED, TWELVE_HOURS, TWENTY_FOUR_HOURS})
public @interface Type {
}

public static final int NONE_SPECIFIED = -1;
public static final int TWELVE_HOURS = 0;
public static final int TWENTY_FOUR_HOURS = 1;
}
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,8 @@ public class NavigationView extends CoordinatorLayout implements LifecycleObserv
private boolean resumeState;
private boolean isInitialized;
private List<Marker> markers = new ArrayList<>();
@NavigationTimeFormat.Type
private int timeFormatType;

public NavigationView(Context context) {
this(context, null);
Expand Down Expand Up @@ -357,9 +359,10 @@ public void updateLocationLayer(Location location) {
public void startNavigation(NavigationViewOptions options) {
clearMarkers();
if (!isInitialized) {
setLocale(options);
establish(options);
navigationViewModel.initializeNavigationOptions(getContext().getApplicationContext(),
options.navigationOptions().toBuilder().isFromNavigationUi(true).build());
navigationViewModel.setTimeFormat(timeFormatType);
initCamera();
setupListeners(options);
subscribeViewModels();
Expand All @@ -369,29 +372,6 @@ public void startNavigation(NavigationViewOptions options) {
routeViewModel.extractRouteOptions(options);
}

private void setLocale(NavigationViewOptions options) {
Locale locale = LocaleUtils.getNonNullLocale(getContext(), options.navigationOptions().locale());
@NavigationUnitType.UnitType int unitType = options.navigationOptions().unitType();

instructionView.setLocale(locale);
instructionView.setUnitType(unitType);
summaryBottomSheet.setLocale(locale);
summaryBottomSheet.setUnitType(unitType);
}

/**
* Should be called after {@link NavigationView#onCreate(Bundle)}.
* <p>
* This method adds the {@link OnNavigationReadyCallback},
* which will fire ready / cancel events for this view.
*
* @param onNavigationReadyCallback to be set to this view
*/
public void getNavigationAsync(OnNavigationReadyCallback onNavigationReadyCallback) {
this.onNavigationReadyCallback = onNavigationReadyCallback;
mapView.getMapAsync(this);
}

/**
* Gives the ability to manipulate the map directly for anything that might not currently be
* supported. This returns null until the view is initialized
Expand All @@ -402,6 +382,26 @@ public MapboxMap getMapboxMap() {
return map;
}

@OnLifecycleEvent(Lifecycle.Event.ON_START)
public void onStart() {
mapView.onStart();
}

@OnLifecycleEvent(Lifecycle.Event.ON_RESUME)
public void onResume() {
mapView.onResume();
}

@OnLifecycleEvent(Lifecycle.Event.ON_PAUSE)
public void onPause() {
mapView.onPause();
}

@OnLifecycleEvent(Lifecycle.Event.ON_STOP)
public void onStop() {
mapView.onStop();
}

private void init() {
InstructionLoader.getInstance().initialize(getContext());
inflate(getContext(), R.layout.navigation_view_layout, this);
Expand Down Expand Up @@ -433,6 +433,48 @@ private void initViewModels() {
}
}

/**
* Adds this view as a lifecycle observer.
* This needs to be done earlier than the other observers (prior to the style loading).
*/
private void initNavigationViewObserver() {
try {
((LifecycleOwner) getContext()).getLifecycle().addObserver(this);
} catch (ClassCastException exception) {
throw new ClassCastException("Please ensure that the provided Context is a valid LifecycleOwner");
}
}

/**
* Initializes the {@link BottomSheetBehavior} for {@link SummaryBottomSheet}.
*/
private void initSummaryBottomSheet() {
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);

if (newState == BottomSheetBehavior.STATE_HIDDEN && navigationPresenter != null) {
navigationPresenter.onSummaryBottomSheetHidden();
}
}

@Override
public void onSlide(@NonNull View bottomSheet, float slideOffset) {
}
});
}

/**
* Initialize a new event dispatcher in charge of firing all navigation
* listener updates to the classes that have implemented these listeners.
*/
private void initNavigationEventDispatcher() {
navigationViewEventDispatcher = new NavigationViewEventDispatcher();
}

/**
* Sets the {@link BottomSheetBehavior} based on the last state stored
* in {@link Bundle} savedInstanceState.
Expand Down Expand Up @@ -465,31 +507,6 @@ private void initRoute() {
mapRoute = new NavigationMapRoute(null, mapView, map, routeStyleRes);
}

/**
* Initializes the {@link NavigationCamera} that will be used to follow
* the {@link Location} updates from {@link MapboxNavigation}.
*/
private void initCamera() {
camera = new NavigationCamera(map, navigationViewModel.getNavigation());
}

/**
* Subscribes the {@link InstructionView} and {@link SummaryBottomSheet} to the {@link NavigationViewModel}.
* <p>
* Then, creates an instance of {@link NavigationViewSubscriber}, which takes a presenter and listener.
* <p>
* The subscriber then subscribes to the view models, setting up the appropriate presenter / listener
* method calls based on the {@link android.arch.lifecycle.LiveData} updates.
*/
private void subscribeViewModels() {
instructionView.subscribe(navigationViewModel);
summaryBottomSheet.subscribe(navigationViewModel);

NavigationViewSubscriber subscriber = new NavigationViewSubscriber(navigationPresenter,
navigationViewEventDispatcher);
subscriber.subscribe(((LifecycleOwner) getContext()), locationViewModel, routeViewModel, navigationViewModel);
}

/**
* Initializes the {@link LocationLayerPlugin} to be used to draw the current
* location.
Expand All @@ -502,18 +519,6 @@ private void initLocationLayer() {
locationLayer.setLocationLayerEnabled(LocationLayerMode.NAVIGATION);
}

/**
* Adds this view as a lifecycle observer.
* This needs to be done earlier than the other observers (prior to the style loading).
*/
private void initNavigationViewObserver() {
try {
((LifecycleOwner) getContext()).getLifecycle().addObserver(this);
} catch (ClassCastException exception) {
throw new ClassCastException("Please ensure that the provided Context is a valid LifecycleOwner");
}
}

/**
* Add lifecycle observers to ensure these objects properly
* start / stop based on the Android lifecycle.
Expand All @@ -527,34 +532,6 @@ private void initLifecycleObservers() {
}
}

/**
* Initialize a new event dispatcher in charge of firing all navigation
* listener updates to the classes that have implemented these listeners.
*/
private void initNavigationEventDispatcher() {
navigationViewEventDispatcher = new NavigationViewEventDispatcher();
}

/**
* Sets up the listeners in the dispatcher, as well as the listeners in the {@link MapboxNavigation}
*
* @param navigationViewOptions that contains all listeners to attach
*/
private void setupListeners(NavigationViewOptions navigationViewOptions) {
navigationViewEventDispatcher.setFeedbackListener(navigationViewOptions.feedbackListener());
navigationViewEventDispatcher.setNavigationListener(navigationViewOptions.navigationListener());
navigationViewEventDispatcher.setRouteListener(navigationViewOptions.routeListener());
navigationViewEventDispatcher.setBottomSheetCallback(navigationViewOptions.bottomSheetCallback());

if (navigationViewOptions.progressChangeListener() != null) {
navigationViewModel.getNavigation().addProgressChangeListener(navigationViewOptions.progressChangeListener());
}

if (navigationViewOptions.milestoneEventListener() != null) {
navigationViewModel.getNavigation().addMilestoneEventListener(navigationViewOptions.milestoneEventListener());
}
}

/**
* Initialize a new presenter for this Activity.
*/
Expand All @@ -581,28 +558,6 @@ public void onClick(View view) {
});
}

/**
* Initializes the {@link BottomSheetBehavior} for {@link SummaryBottomSheet}.
*/
private void initSummaryBottomSheet() {
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);

if (newState == BottomSheetBehavior.STATE_HIDDEN && navigationPresenter != null) {
navigationPresenter.onSummaryBottomSheetHidden();
}
}

@Override
public void onSlide(@NonNull View bottomSheet, float slideOffset) {
}
});
}

/**
* Removes any markers on the map that were added using addMarker()
*/
Expand All @@ -612,23 +567,85 @@ private void clearMarkers() {
}
}

@OnLifecycleEvent(Lifecycle.Event.ON_START)
public void onStart() {
mapView.onStart();
private void establish(NavigationViewOptions options) {
establishLocale(options);
establishUnitType(options);
establishTimeFormat(options);
}

@OnLifecycleEvent(Lifecycle.Event.ON_RESUME)
public void onResume() {
mapView.onResume();
private void establishLocale(NavigationViewOptions options) {
Locale locale = LocaleUtils.getNonNullLocale(getContext(), options.navigationOptions().locale());
instructionView.setLocale(locale);
summaryBottomSheet.setLocale(locale);
}

@OnLifecycleEvent(Lifecycle.Event.ON_PAUSE)
public void onPause() {
mapView.onPause();
private void establishUnitType(NavigationViewOptions options) {
@NavigationUnitType.UnitType
int unitType = options.navigationOptions().unitType();
instructionView.setUnitType(unitType);
summaryBottomSheet.setUnitType(unitType);
}

@OnLifecycleEvent(Lifecycle.Event.ON_STOP)
public void onStop() {
mapView.onStop();
private void establishTimeFormat(NavigationViewOptions options) {
timeFormatType = options.timeFormatType();
summaryBottomSheet.setTimeFormat(timeFormatType);
}

/**
* Initializes the {@link NavigationCamera} that will be used to follow
* the {@link Location} updates from {@link MapboxNavigation}.
*/
private void initCamera() {
camera = new NavigationCamera(map, navigationViewModel.getNavigation());
}

/**
* Sets up the listeners in the dispatcher, as well as the listeners in the {@link MapboxNavigation}
*
* @param navigationViewOptions that contains all listeners to attach
*/
private void setupListeners(NavigationViewOptions navigationViewOptions) {
navigationViewEventDispatcher.setFeedbackListener(navigationViewOptions.feedbackListener());
navigationViewEventDispatcher.setNavigationListener(navigationViewOptions.navigationListener());
navigationViewEventDispatcher.setRouteListener(navigationViewOptions.routeListener());
navigationViewEventDispatcher.setBottomSheetCallback(navigationViewOptions.bottomSheetCallback());

if (navigationViewOptions.progressChangeListener() != null) {
navigationViewModel.getNavigation().addProgressChangeListener(navigationViewOptions.progressChangeListener());
}

if (navigationViewOptions.milestoneEventListener() != null) {
navigationViewModel.getNavigation().addMilestoneEventListener(navigationViewOptions.milestoneEventListener());
}
}

/**
* Subscribes the {@link InstructionView} and {@link SummaryBottomSheet} to the {@link NavigationViewModel}.
* <p>
* Then, creates an instance of {@link NavigationViewSubscriber}, which takes a presenter and listener.
* <p>
* The subscriber then subscribes to the view models, setting up the appropriate presenter / listener
* method calls based on the {@link android.arch.lifecycle.LiveData} updates.
*/
private void subscribeViewModels() {
instructionView.subscribe(navigationViewModel);
summaryBottomSheet.subscribe(navigationViewModel);

NavigationViewSubscriber subscriber = new NavigationViewSubscriber(navigationPresenter,
navigationViewEventDispatcher);
subscriber.subscribe(((LifecycleOwner) getContext()), locationViewModel, routeViewModel, navigationViewModel);
}

/**
* Should be called after {@link NavigationView#onCreate(Bundle)}.
* <p>
* This method adds the {@link OnNavigationReadyCallback},
* which will fire ready / cancel events for this view.
*
* @param onNavigationReadyCallback to be set to this view
*/
public void getNavigationAsync(OnNavigationReadyCallback onNavigationReadyCallback) {
this.onNavigationReadyCallback = onNavigationReadyCallback;
mapView.getMapAsync(this);
}
}
Loading

0 comments on commit d4cd5da

Please sign in to comment.