Skip to content

Add route overview button and animation to NavigationView#967

Merged
danesfeder merged 1 commit into
masterfrom
dan-route-overview
Jun 19, 2018
Merged

Add route overview button and animation to NavigationView#967
danesfeder merged 1 commit into
masterfrom
dan-route-overview

Conversation

@danesfeder
Copy link
Copy Markdown
Contributor

@danesfeder danesfeder commented May 23, 2018

Closes #950

TODO:

  • Add button with chosen asset from @cjballard
  • Show resume button after overview clicked
  • Add test for dynamic camera providing list of Point

Animation running wired up to the X button:
ezgif com-video-to-gif 1

cc @brsbl

@danesfeder danesfeder added ⚠️ DO NOT MERGE PR should not be merged! platform parity Required to keep on par with iOS. topic: camera labels May 23, 2018
@danesfeder danesfeder added this to the 0.14.0 milestone May 23, 2018
@danesfeder danesfeder self-assigned this May 23, 2018
@Cjballard-zz
Copy link
Copy Markdown

routepreview_icons.zip

Attaching light and dark icons for route preview. @danesfeder

@brsbl-zz
Copy link
Copy Markdown

brsbl-zz commented May 24, 2018

Love the dynamic camera.

@danesfeder is it easy enough to adjust the spacing between the sound and feedback icons in this PR as well so they better match iOS? the thinking being grouping things that obscure the map together makes them less intrusive overall -- thoughts @cjballard?

also:

  • Cut a ticket in /mapbox-navigation-ios to mirror this behavior 🙂

@danesfeder
Copy link
Copy Markdown
Contributor Author

danesfeder commented May 24, 2018

@brsbl sure thing and thanks! - would like @cjballard 👀 on this as well. I have them spaced a little more to create larger touch points. Hitting that feedback button accidentally when you're trying to mute is pretty jarring

@Cjballard-zz
Copy link
Copy Markdown

@brsbl @danesfeder Agreed. I think there's a middle ground we can hit that still reserves those touchpoints while grouping them more tightly and revealing more of the map. Maybe 10-20dp closer together could work.

@danesfeder danesfeder modified the milestones: 0.14.0, 0.15.0 May 30, 2018
@danesfeder danesfeder force-pushed the dan-route-overview branch 3 times, most recently from 9528c6b to 7ece39c Compare June 5, 2018 13:07
@danesfeder
Copy link
Copy Markdown
Contributor Author

@cjballard Here's what the current setup looks like, let me know what you think / want to tweak 👍

Portrait

ezgif com-video-to-gif

Landscape

ezgif com-video-to-gif 1

@Cjballard-zz
Copy link
Copy Markdown

@danesfeder Looks good to me! Only adjustment I might make is to make the separating line a bit shorter, closer to the height (but still a little taller) than the route preview icon:

tt-example

@danesfeder danesfeder force-pushed the dan-route-overview branch from 2ae7846 to d60a781 Compare June 5, 2018 20:47
@danesfeder
Copy link
Copy Markdown
Contributor Author

@cjballard Updated:
device-2018-06-05-164139

device-2018-06-05-164333

@Cjballard-zz
Copy link
Copy Markdown

@danesfeder Looks good to me 👍

@danesfeder
Copy link
Copy Markdown
Contributor Author

@cjballard awesome, thank you!

@Guardiola31337 @devotaaabel will add tests to this PR tomorrow then will be good for 👀

@danesfeder danesfeder force-pushed the dan-route-overview branch 3 times, most recently from 386c01d to d0236e2 Compare June 6, 2018 14:23
@danesfeder
Copy link
Copy Markdown
Contributor Author

Tests added - this is good for 👀

@danesfeder danesfeder removed the ⚠️ DO NOT MERGE PR should not be merged! label Jun 6, 2018
@danesfeder danesfeder changed the title [WIP] Add route overview button and animation to NavigationView Add route overview button and animation to NavigationView Jun 6, 2018
@danesfeder
Copy link
Copy Markdown
Contributor Author

Merge is causing issues with padding adjustments - this PR is no longer ready for review until these issues are fixed.

@danesfeder danesfeder added ⚠️ DO NOT MERGE PR should not be merged! and removed ✓ ready for review labels Jun 7, 2018
@danesfeder danesfeder force-pushed the dan-route-overview branch 4 times, most recently from c6c9676 to 35966d2 Compare June 8, 2018 20:11
@danesfeder danesfeder added ✓ ready for review and removed ⚠️ DO NOT MERGE PR should not be merged! labels Jun 11, 2018
@danesfeder danesfeder force-pushed the dan-route-overview branch 2 times, most recently from 1ccb3e9 to 717f146 Compare June 13, 2018 16:23
Copy link
Copy Markdown
Contributor

@Guardiola31337 Guardiola31337 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Overall this look awesome 💯 Great job @danesfeder 👏
Really nice test coverage ❤️

Some minor comments.

navigationPresenter.onRecenterClick();
}
});
routeOverviewBtn.setOnClickListener(new OnClickListener() {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What about extracting the listeners into class properties?

}

@NonNull
private RouteInformation buildRouteInformationFromRouteProgress(RouteProgress routeProgress) {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Minor thing - IMO buildRouteInformationFrom(RouteProgress routeProgress) would be clearer and to the point. What do you think?

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

CameraPosition resetPosition = new CameraPosition.Builder().tilt(0).bearing(0).build();
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can move these two lines after the guard clause avoiding instantiating them if invalidPoints is true.

if (invalidPoints) {
return;
}
final LatLngBounds routeBounds = convertRoutePointsToLatLngBounds(routePoints);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What about extracting this preparation block of code into a well-named private method? (Including the two lines mentioned above ☝️)

ImageButton routeOverviewBtn = findViewById(R.id.routeOverviewBtn);
boolean isDarkThemeEnabled = ThemeSwitcher.isDarkThemeEnabled(getContext());
Drawable routeOverviewDrawable;
if (isDarkThemeEnabled) {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you add a custom attribute to the nav theme so it's just added upon inflation and remove the if else check?

LineString lineString = LineString.fromPolyline(route.geometry(), Constants.PRECISION_6);
return lineString.coordinates();
}
return null;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should consider returning a Null Object instead or even better try to getting rid of it at all (maybe returning an empty list?). If not, code becomes defensive and full of null checks.

👀 Null References: The Billion Dollar Mistake

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually if the route in setupLineStringAndBearing is null L#85 will cause a NPE right?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In any case, guard clauses normally are at the beginning of the method representing the unexpected behavior.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also saw the same exact code in DynamicCameraTest.java (generateRouteCoordinates). Should be abstracted and accessible to the implementation classes?


@Test
public void onInformationFromRoute_engineCreatesOverviewPointList() throws Exception {
MapboxMap mapboxMap = mock(MapboxMap.class);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Minor thing - Could we extract some shared "arrangement" code into private methods and used it across the tests? This applies to MapWaynameTest as well.

@danesfeder danesfeder force-pushed the dan-route-overview branch 4 times, most recently from 5cb0ecc to 74d0d02 Compare June 18, 2018 20:58
@danesfeder
Copy link
Copy Markdown
Contributor Author

@Guardiola31337 Updated - I skipped your comment on MapWaynameTest - the variables that are out of the builders are being used to provide context / used in the actual tests so they cannot be pushed into the builders.

@danesfeder danesfeder force-pushed the dan-route-overview branch from 74d0d02 to a5af67c Compare June 18, 2018 21:01
Copy link
Copy Markdown
Contributor

@Guardiola31337 Guardiola31337 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@danesfeder Some minor new comments from the latest changes.

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

public class NavigationSnapshotReadyCallback implements MapboxMap.SnapshotReadyCallback {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Access can be package-private

private NavigationView navigationView;
private NavigationViewModel navigationViewModel;

public NavigationSnapshotReadyCallback(NavigationView navigationView, NavigationViewModel navigationViewModel) {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Access can be package-private

boolean darkThemeEnabled = isDarkThemeEnabled(context);
updatePreferencesDarkEnabled(context, darkThemeEnabled);

// Check for custom theme from NavigationLauncher
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this comment necessary?

}

@NonNull
private RouteInformation buildRouteInformationFrom(RouteProgress routeProgress) {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

#967 (comment)

Didn't see that we had other buildRouteInformationFrom methods. Maybe we should leave as it was. Sorry for the confusion.

if (invalidPoints) {
return;
}
CameraUpdate resetUpdate = buildResetCameraUpdate();
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

CameraUpdate resetUpdate = buildResetCameraUpdate();
final CameraUpdate overviewUpdate = buildOverviewCameraUpdate(padding, routePoints);

mapboxMap.animateCamera(resetUpdate, 150, new MapboxMap.CancelableCallback() {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What about extracting the listeners into class properties?

return response.routes().get(0);
}

private List<Point> generateRouteCoordinates(DirectionsRoute route) {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

}

public static float dpToPx(Context context, int dp) {
public static int[] buildRouteOverviewPadding(Context context) {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This doesn't sound like a View utility. It's only used in NavigationView. IMO, objects and methods should live/be where their context is. From my experience utility classes become a drawer easily and we should treat them carefully.

}

@Override
public List<Point> overview(RouteInformation routeInformation) {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IMO overview is getting too long.
What about extracting blocks of code into well-named private methods and simplifying conditional expressions somehow?

We should keep public methods as clean as possible so they read like pseudocode (i.e. no conditionals, fors, etc.).

@danesfeder danesfeder force-pushed the dan-route-overview branch 2 times, most recently from 63409b0 to 47c98ea Compare June 19, 2018 14:14
@danesfeder danesfeder force-pushed the dan-route-overview branch from 47c98ea to 512390e Compare June 19, 2018 14:24
Copy link
Copy Markdown
Contributor

@Guardiola31337 Guardiola31337 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well done @danesfeder :shipit:

@danesfeder danesfeder merged commit abe86a5 into master Jun 19, 2018
@danesfeder danesfeder deleted the dan-route-overview branch June 19, 2018 14:46
@danesfeder danesfeder mentioned this pull request Jun 21, 2018
11 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

platform parity Required to keep on par with iOS.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants