Skip to content
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
@@ -1,13 +1,18 @@
package com.mapbox.services.android.navigation.testapp.activity.navigationui;

import android.content.SharedPreferences;
import android.content.res.Configuration;
import android.location.Location;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.support.annotation.IdRes;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.design.widget.BottomSheetBehavior;
import android.support.design.widget.CoordinatorLayout;
import android.support.design.widget.FloatingActionButton;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.app.AppCompatDelegate;
import android.text.SpannableString;
import android.text.Spanned;
import android.text.style.AbsoluteSizeSpan;
Expand All @@ -34,105 +39,38 @@
public class EmbeddedNavigationActivity extends AppCompatActivity implements OnNavigationReadyCallback,
NavigationListener, ProgressChangeListener, InstructionListListener {

private static final Point ORIGIN = Point.fromLngLat(-77.03194990754128, 38.909664963450105);
private static final Point DESTINATION = Point.fromLngLat(-77.0270025730133, 38.91057077063121);

private NavigationView navigationView;
private View spacer;
private TextView speedWidget;
private static final Point ORIGIN = Point.fromLngLat(-77.03194990754128, 38.909664963450105);
private static final Point DESTINATION = Point.fromLngLat(-77.0270025730133, 38.91057077063121);
private FloatingActionButton fabNightModeToggle;

private boolean bottomSheetVisible = true;
private boolean instructionListShown = false;

@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
setTheme(R.style.Theme_AppCompat_Light_NoActionBar);
initNightMode();
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_embedded_navigation);
navigationView = findViewById(R.id.navigationView);
navigationView.onCreate(savedInstanceState);

fabNightModeToggle = findViewById(R.id.fabToggleNightMode);
speedWidget = findViewById(R.id.speed_limit);
spacer = findViewById(R.id.spacer);
setSpeedWidgetAnchor(R.id.summaryBottomSheet);

navigationView.onCreate(savedInstanceState);
navigationView.initialize(this);
}

/**
* Sets the anchor of the spacer for the speed widget, thus setting the anchor for the speed widget
* (The speed widget is anchored to the spacer, which is there because padding between items and
* their anchors in CoordinatorLayouts is finicky.
* @param res resource for view of which to anchor the spacer
*/
private void setSpeedWidgetAnchor(@IdRes int res) {
CoordinatorLayout.LayoutParams layoutParams = (CoordinatorLayout.LayoutParams) spacer.getLayoutParams();
layoutParams.setAnchorId(res);
spacer.setLayoutParams(layoutParams);
}

@Override
public void onNavigationReady() {
fetchRoute();
}

private void startNavigation(DirectionsRoute directionsRoute) {
NavigationViewOptions.Builder options =
NavigationViewOptions.builder()
.navigationListener(this)
.directionsRoute(directionsRoute)
.shouldSimulateRoute(true)
.progressChangeListener(this)
.instructionListListener(this);
setBottomSheetCallback(options);

navigationView.startNavigation(options.build());
}

private void fetchRoute() {
NavigationRoute.builder(this)
.accessToken(Mapbox.getAccessToken())
.origin(ORIGIN)
.destination(DESTINATION)
.alternatives(true)
.build()
.getRoute(new SimplifiedCallback() {
@Override
public void onResponse(Call<DirectionsResponse> call, Response<DirectionsResponse> response) {
DirectionsRoute directionsRoute = response.body().routes().get(0);
startNavigation(directionsRoute);
}
});
}

private void setBottomSheetCallback(NavigationViewOptions.Builder options) {
options.bottomSheetCallback(new BottomSheetBehavior.BottomSheetCallback() {
@Override
public void onStateChanged(@NonNull View bottomSheet, int newState) {
switch (newState) {
case BottomSheetBehavior.STATE_HIDDEN:
bottomSheetVisible = false;
setSpeedWidgetAnchor(R.id.recenterBtn);
break;
case BottomSheetBehavior.STATE_EXPANDED:
bottomSheetVisible = true;
break;
case BottomSheetBehavior.STATE_SETTLING:
if (!bottomSheetVisible) {
// View needs to be anchored to the bottom sheet before it is finished expanding
// because of the animation
setSpeedWidgetAnchor(R.id.summaryBottomSheet);
}
break;
default:
return;
}
}

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

@Override
public void onStart() {
super.onStart();
Expand Down Expand Up @@ -187,6 +125,7 @@ public void onStop() {
protected void onDestroy() {
super.onDestroy();
navigationView.onDestroy();
saveNightModeToPreferences(AppCompatDelegate.MODE_NIGHT_AUTO);
}

@Override
Expand All @@ -210,6 +149,134 @@ public void onProgressChange(Location location, RouteProgress routeProgress) {
setSpeed(location);
}

@Override
public void onInstructionListVisibilityChanged(boolean shown) {
instructionListShown = shown;
speedWidget.setVisibility(shown ? View.GONE : View.VISIBLE);
if (instructionListShown) {
fabNightModeToggle.hide();
} else if (bottomSheetVisible) {
fabNightModeToggle.show();
}
}

private void startNavigation(DirectionsRoute directionsRoute) {
NavigationViewOptions.Builder options =
NavigationViewOptions.builder()
.navigationListener(this)
.directionsRoute(directionsRoute)
.shouldSimulateRoute(true)
.progressChangeListener(this)
.instructionListListener(this);
setBottomSheetCallback(options);
setupNightModeFab();

navigationView.startNavigation(options.build());
}

private void fetchRoute() {
NavigationRoute.builder(this)
.accessToken(Mapbox.getAccessToken())
.origin(ORIGIN)
.destination(DESTINATION)
.alternatives(true)
.build()
.getRoute(new SimplifiedCallback() {
@Override
public void onResponse(Call<DirectionsResponse> call, Response<DirectionsResponse> response) {
DirectionsRoute directionsRoute = response.body().routes().get(0);
startNavigation(directionsRoute);
}
});
}

/**
* Sets the anchor of the spacer for the speed widget, thus setting the anchor for the speed widget
* (The speed widget is anchored to the spacer, which is there because padding between items and
* their anchors in CoordinatorLayouts is finicky.
*
* @param res resource for view of which to anchor the spacer
*/
private void setSpeedWidgetAnchor(@IdRes int res) {
CoordinatorLayout.LayoutParams layoutParams = (CoordinatorLayout.LayoutParams) spacer.getLayoutParams();
layoutParams.setAnchorId(res);
spacer.setLayoutParams(layoutParams);
}

private void setBottomSheetCallback(NavigationViewOptions.Builder options) {
options.bottomSheetCallback(new BottomSheetBehavior.BottomSheetCallback() {
@Override
public void onStateChanged(@NonNull View bottomSheet, int newState) {
switch (newState) {
case BottomSheetBehavior.STATE_HIDDEN:
bottomSheetVisible = false;
fabNightModeToggle.hide();
setSpeedWidgetAnchor(R.id.recenterBtn);
break;
case BottomSheetBehavior.STATE_EXPANDED:
bottomSheetVisible = true;
break;
case BottomSheetBehavior.STATE_SETTLING:
if (!bottomSheetVisible) {
// View needs to be anchored to the bottom sheet before it is finished expanding
// because of the animation
fabNightModeToggle.show();
setSpeedWidgetAnchor(R.id.summaryBottomSheet);
}
break;
default:
return;
}
}

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

private void setupNightModeFab() {
fabNightModeToggle.setOnClickListener(view -> toggleNightMode());
}

private void toggleNightMode() {
int currentNightMode = getCurrentNightMode();
alternateNightMode(currentNightMode);
}

private void initNightMode() {
int nightMode = retrieveNightModeFromPreferences();
AppCompatDelegate.setDefaultNightMode(nightMode);
}

private int getCurrentNightMode() {
return getResources().getConfiguration().uiMode
& Configuration.UI_MODE_NIGHT_MASK;
}

private void alternateNightMode(int currentNightMode) {
int newNightMode;
if (currentNightMode == Configuration.UI_MODE_NIGHT_YES) {
newNightMode = AppCompatDelegate.MODE_NIGHT_NO;
} else {
newNightMode = AppCompatDelegate.MODE_NIGHT_YES;
}
saveNightModeToPreferences(newNightMode);
recreate();
}

private int retrieveNightModeFromPreferences() {
SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(this);
return preferences.getInt(getString(R.string.current_night_mode), AppCompatDelegate.MODE_NIGHT_AUTO);
}

private void saveNightModeToPreferences(int nightMode) {
SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(this);
SharedPreferences.Editor editor = preferences.edit();
editor.putInt(getString(R.string.current_night_mode), nightMode);
editor.apply();
}

private void setSpeed(Location location) {
String string = String.format("%d\nMPH", (int) (location.getSpeed() * 2.2369));
int mphTextSize = getResources().getDimensionPixelSize(R.dimen.mph_text_size);
Expand All @@ -227,10 +294,4 @@ private void setSpeed(Location location) {
speedWidget.setVisibility(View.VISIBLE);
}
}

@Override
public void onInstructionListVisibilityChanged(boolean shown) {
instructionListShown = shown;
speedWidget.setVisibility(shown ? View.GONE : View.VISIBLE);
}
}
9 changes: 9 additions & 0 deletions app/src/main/res/drawable/ic_refresh.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24.0"
android:viewportHeight="24.0">
<path
android:fillColor="#FF000000"
android:pathData="M12,6v3l4,-4 -4,-4v3c-4.42,0 -8,3.58 -8,8 0,1.57 0.46,3.03 1.24,4.26L6.7,14.8c-0.45,-0.83 -0.7,-1.79 -0.7,-2.8 0,-3.31 2.69,-6 6,-6zM18.76,7.74L17.3,9.2c0.44,0.84 0.7,1.79 0.7,2.8 0,3.31 -2.69,6 -6,6v-3l-4,4 4,4v-3c4.42,0 8,-3.58 8,-8 0,-1.57 -0.46,-3.03 -1.24,-4.26z"/>
</vector>
44 changes: 30 additions & 14 deletions app/src/main/res/layout/activity_embedded_navigation.xml
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
<android.support.design.widget.CoordinatorLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
Expand All @@ -8,28 +9,43 @@
android:id="@+id/navigationView"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:navigationLightTheme="@style/CustomNavigationView"
app:navigationDarkTheme="@style/NavigationViewDark"/>
<TextView
app:navigationDarkTheme="@style/NavigationViewDark"
app:navigationLightTheme="@style/CustomNavigationView"/>

<android.support.design.widget.FloatingActionButton
android:id="@+id/fabToggleNightMode"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="top|start"
android:layout_marginEnd="16dp"
android:layout_marginRight="16dp"
android:tint="@android:color/white"
app:layout_anchor="@id/spacer"
app:layout_anchorGravity="top|end"
app:srcCompat="@drawable/ic_refresh"/>

<TextView
android:id="@+id/speed_limit"
android:textSize="35sp"
android:padding="6dp"
app:layout_anchorGravity="top"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="top"
android:gravity="center"
android:layout_marginLeft="16dp"
android:background="@android:color/white"
android:elevation="3dp"
app:layout_anchor="@id/spacer"
android:gravity="center"
android:padding="6dp"
android:textColor="@android:color/black"
android:background="@android:color/white"
android:visibility="gone"/>
android:textSize="35sp"
android:visibility="gone"
app:layout_anchor="@id/spacer"
app:layout_anchorGravity="top"/>

<View
android:id="@+id/spacer"
android:layout_width="wrap_content"
android:layout_height="6dp"
android:id="@+id/spacer"
android:layout_gravity="top"
android:background="@android:color/transparent"
app:layout_anchorGravity="top"
android:layout_gravity="top"/>
app:layout_anchorGravity="top"/>

</android.support.design.widget.CoordinatorLayout>
1 change: 1 addition & 0 deletions app/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
<string name="route_profile_key" translatable="false">route_profile</string>
<string name="default_locale" translatable="false">default_for_device</string>
<string name="default_unit_type" translatable="false">default_for_device</string>
<string name="current_night_mode" translatable="false">current_night_mode</string>

<string name="error_route_not_available">Current route is not available</string>
<string name="error_select_longer_route">Please select a longer route</string>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import android.preference.PreferenceManager;
import android.support.annotation.Nullable;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.app.AppCompatDelegate;

import com.mapbox.api.directions.v5.DirectionsCriteria;
import com.mapbox.api.directions.v5.models.DirectionsRoute;
Expand All @@ -26,6 +27,7 @@ public class MapboxNavigationActivity extends AppCompatActivity implements OnNav
protected void onCreate(@Nullable Bundle savedInstanceState) {
setTheme(R.style.Theme_AppCompat_NoActionBar);
super.onCreate(savedInstanceState);
AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_AUTO);
setContentView(R.layout.activity_navigation);
navigationView = findViewById(R.id.navigationView);
navigationView.onCreate(savedInstanceState);
Expand Down
Loading