Add pan and zoom feature in `PlaceListNavigationTemplate` and `RoutePreviewNavigationTemplate`
Bug: 200328371
Test: unit test
Relnote: Added support for panning and zooming in `PlaceListNavigationTemplate` and `RoutePreviewNavigationTemplate`
Change-Id: I9d8a3ff7751ffd5423201b2f29886adff38e8bde
diff --git a/car/app/app/api/public_plus_experimental_1.1.0-beta02.txt b/car/app/app/api/public_plus_experimental_1.1.0-beta02.txt
index e43b6f474..d688300 100644
--- a/car/app/app/api/public_plus_experimental_1.1.0-beta02.txt
+++ b/car/app/app/api/public_plus_experimental_1.1.0-beta02.txt
@@ -1200,6 +1200,8 @@
method public androidx.car.app.model.ActionStrip? getActionStrip();
method public androidx.car.app.model.Action? getHeaderAction();
method public androidx.car.app.model.ItemList? getItemList();
+ method @androidx.car.app.annotations.ExperimentalCarApi @androidx.car.app.annotations.RequiresCarApi(4) public androidx.car.app.model.ActionStrip? getMapActionStrip();
+ method @androidx.car.app.annotations.ExperimentalCarApi @androidx.car.app.annotations.RequiresCarApi(4) public androidx.car.app.navigation.model.PanModeDelegate? getPanModeDelegate();
method public androidx.car.app.model.CarText? getTitle();
method public boolean isLoading();
}
@@ -1211,6 +1213,8 @@
method public androidx.car.app.navigation.model.PlaceListNavigationTemplate.Builder setHeaderAction(androidx.car.app.model.Action);
method public androidx.car.app.navigation.model.PlaceListNavigationTemplate.Builder setItemList(androidx.car.app.model.ItemList);
method public androidx.car.app.navigation.model.PlaceListNavigationTemplate.Builder setLoading(boolean);
+ method @androidx.car.app.annotations.ExperimentalCarApi @androidx.car.app.annotations.RequiresCarApi(4) public androidx.car.app.navigation.model.PlaceListNavigationTemplate.Builder setMapActionStrip(androidx.car.app.model.ActionStrip);
+ method @androidx.car.app.annotations.ExperimentalCarApi @androidx.car.app.annotations.RequiresCarApi(4) public androidx.car.app.navigation.model.PlaceListNavigationTemplate.Builder setPanModeListener(androidx.car.app.navigation.model.PanModeListener);
method public androidx.car.app.navigation.model.PlaceListNavigationTemplate.Builder setTitle(CharSequence);
method public androidx.car.app.navigation.model.PlaceListNavigationTemplate.Builder setTitle(androidx.car.app.model.CarText);
}
@@ -1219,7 +1223,9 @@
method public androidx.car.app.model.ActionStrip? getActionStrip();
method public androidx.car.app.model.Action? getHeaderAction();
method public androidx.car.app.model.ItemList? getItemList();
+ method @androidx.car.app.annotations.ExperimentalCarApi @androidx.car.app.annotations.RequiresCarApi(4) public androidx.car.app.model.ActionStrip? getMapActionStrip();
method public androidx.car.app.model.Action? getNavigateAction();
+ method @androidx.car.app.annotations.ExperimentalCarApi @androidx.car.app.annotations.RequiresCarApi(4) public androidx.car.app.navigation.model.PanModeDelegate? getPanModeDelegate();
method public androidx.car.app.model.CarText? getTitle();
method public boolean isLoading();
}
@@ -1231,7 +1237,9 @@
method public androidx.car.app.navigation.model.RoutePreviewNavigationTemplate.Builder setHeaderAction(androidx.car.app.model.Action);
method public androidx.car.app.navigation.model.RoutePreviewNavigationTemplate.Builder setItemList(androidx.car.app.model.ItemList);
method public androidx.car.app.navigation.model.RoutePreviewNavigationTemplate.Builder setLoading(boolean);
+ method @androidx.car.app.annotations.ExperimentalCarApi @androidx.car.app.annotations.RequiresCarApi(4) public androidx.car.app.navigation.model.RoutePreviewNavigationTemplate.Builder setMapActionStrip(androidx.car.app.model.ActionStrip);
method public androidx.car.app.navigation.model.RoutePreviewNavigationTemplate.Builder setNavigateAction(androidx.car.app.model.Action);
+ method @androidx.car.app.annotations.ExperimentalCarApi @androidx.car.app.annotations.RequiresCarApi(4) public androidx.car.app.navigation.model.RoutePreviewNavigationTemplate.Builder setPanModeListener(androidx.car.app.navigation.model.PanModeListener);
method public androidx.car.app.navigation.model.RoutePreviewNavigationTemplate.Builder setTitle(CharSequence);
method public androidx.car.app.navigation.model.RoutePreviewNavigationTemplate.Builder setTitle(androidx.car.app.model.CarText);
}
diff --git a/car/app/app/api/public_plus_experimental_current.txt b/car/app/app/api/public_plus_experimental_current.txt
index e43b6f474..d688300 100644
--- a/car/app/app/api/public_plus_experimental_current.txt
+++ b/car/app/app/api/public_plus_experimental_current.txt
@@ -1200,6 +1200,8 @@
method public androidx.car.app.model.ActionStrip? getActionStrip();
method public androidx.car.app.model.Action? getHeaderAction();
method public androidx.car.app.model.ItemList? getItemList();
+ method @androidx.car.app.annotations.ExperimentalCarApi @androidx.car.app.annotations.RequiresCarApi(4) public androidx.car.app.model.ActionStrip? getMapActionStrip();
+ method @androidx.car.app.annotations.ExperimentalCarApi @androidx.car.app.annotations.RequiresCarApi(4) public androidx.car.app.navigation.model.PanModeDelegate? getPanModeDelegate();
method public androidx.car.app.model.CarText? getTitle();
method public boolean isLoading();
}
@@ -1211,6 +1213,8 @@
method public androidx.car.app.navigation.model.PlaceListNavigationTemplate.Builder setHeaderAction(androidx.car.app.model.Action);
method public androidx.car.app.navigation.model.PlaceListNavigationTemplate.Builder setItemList(androidx.car.app.model.ItemList);
method public androidx.car.app.navigation.model.PlaceListNavigationTemplate.Builder setLoading(boolean);
+ method @androidx.car.app.annotations.ExperimentalCarApi @androidx.car.app.annotations.RequiresCarApi(4) public androidx.car.app.navigation.model.PlaceListNavigationTemplate.Builder setMapActionStrip(androidx.car.app.model.ActionStrip);
+ method @androidx.car.app.annotations.ExperimentalCarApi @androidx.car.app.annotations.RequiresCarApi(4) public androidx.car.app.navigation.model.PlaceListNavigationTemplate.Builder setPanModeListener(androidx.car.app.navigation.model.PanModeListener);
method public androidx.car.app.navigation.model.PlaceListNavigationTemplate.Builder setTitle(CharSequence);
method public androidx.car.app.navigation.model.PlaceListNavigationTemplate.Builder setTitle(androidx.car.app.model.CarText);
}
@@ -1219,7 +1223,9 @@
method public androidx.car.app.model.ActionStrip? getActionStrip();
method public androidx.car.app.model.Action? getHeaderAction();
method public androidx.car.app.model.ItemList? getItemList();
+ method @androidx.car.app.annotations.ExperimentalCarApi @androidx.car.app.annotations.RequiresCarApi(4) public androidx.car.app.model.ActionStrip? getMapActionStrip();
method public androidx.car.app.model.Action? getNavigateAction();
+ method @androidx.car.app.annotations.ExperimentalCarApi @androidx.car.app.annotations.RequiresCarApi(4) public androidx.car.app.navigation.model.PanModeDelegate? getPanModeDelegate();
method public androidx.car.app.model.CarText? getTitle();
method public boolean isLoading();
}
@@ -1231,7 +1237,9 @@
method public androidx.car.app.navigation.model.RoutePreviewNavigationTemplate.Builder setHeaderAction(androidx.car.app.model.Action);
method public androidx.car.app.navigation.model.RoutePreviewNavigationTemplate.Builder setItemList(androidx.car.app.model.ItemList);
method public androidx.car.app.navigation.model.RoutePreviewNavigationTemplate.Builder setLoading(boolean);
+ method @androidx.car.app.annotations.ExperimentalCarApi @androidx.car.app.annotations.RequiresCarApi(4) public androidx.car.app.navigation.model.RoutePreviewNavigationTemplate.Builder setMapActionStrip(androidx.car.app.model.ActionStrip);
method public androidx.car.app.navigation.model.RoutePreviewNavigationTemplate.Builder setNavigateAction(androidx.car.app.model.Action);
+ method @androidx.car.app.annotations.ExperimentalCarApi @androidx.car.app.annotations.RequiresCarApi(4) public androidx.car.app.navigation.model.RoutePreviewNavigationTemplate.Builder setPanModeListener(androidx.car.app.navigation.model.PanModeListener);
method public androidx.car.app.navigation.model.RoutePreviewNavigationTemplate.Builder setTitle(CharSequence);
method public androidx.car.app.navigation.model.RoutePreviewNavigationTemplate.Builder setTitle(androidx.car.app.model.CarText);
}
diff --git a/car/app/app/src/main/java/androidx/car/app/model/constraints/ActionsConstraints.java b/car/app/app/src/main/java/androidx/car/app/model/constraints/ActionsConstraints.java
index b2ac358..0675d63 100644
--- a/car/app/app/src/main/java/androidx/car/app/model/constraints/ActionsConstraints.java
+++ b/car/app/app/src/main/java/androidx/car/app/model/constraints/ActionsConstraints.java
@@ -93,12 +93,12 @@
.build();
/**
- * Constraints for map action buttons in navigation templates.
+ * Constraints for map action buttons.
*
* <p>Only buttons with icons are allowed.
*/
@NonNull
- public static final ActionsConstraints ACTIONS_CONSTRAINTS_NAVIGATION_MAP =
+ public static final ActionsConstraints ACTIONS_CONSTRAINTS_MAP =
new ActionsConstraints.Builder(ACTIONS_CONSTRAINTS_CONSERVATIVE)
.setMaxActions(4)
.build();
diff --git a/car/app/app/src/main/java/androidx/car/app/navigation/model/NavigationTemplate.java b/car/app/app/src/main/java/androidx/car/app/navigation/model/NavigationTemplate.java
index a95b950..d157202 100644
--- a/car/app/app/src/main/java/androidx/car/app/navigation/model/NavigationTemplate.java
+++ b/car/app/app/src/main/java/androidx/car/app/navigation/model/NavigationTemplate.java
@@ -16,8 +16,8 @@
package androidx.car.app.navigation.model;
+import static androidx.car.app.model.constraints.ActionsConstraints.ACTIONS_CONSTRAINTS_MAP;
import static androidx.car.app.model.constraints.ActionsConstraints.ACTIONS_CONSTRAINTS_NAVIGATION;
-import static androidx.car.app.model.constraints.ActionsConstraints.ACTIONS_CONSTRAINTS_NAVIGATION_MAP;
import static androidx.car.app.model.constraints.CarColorConstraints.UNCONSTRAINED;
import static java.util.Objects.requireNonNull;
@@ -283,7 +283,6 @@
@Nullable
PanModeDelegate mPanModeDelegate;
-
/**
* Sets the navigation information to display on the template.
*
@@ -375,7 +374,7 @@
@RequiresCarApi(2)
@NonNull
public Builder setMapActionStrip(@NonNull ActionStrip actionStrip) {
- ACTIONS_CONSTRAINTS_NAVIGATION_MAP.validateOrThrow(
+ ACTIONS_CONSTRAINTS_MAP.validateOrThrow(
requireNonNull(actionStrip).getActions());
mMapActionStrip = actionStrip;
return this;
diff --git a/car/app/app/src/main/java/androidx/car/app/navigation/model/PlaceListNavigationTemplate.java b/car/app/app/src/main/java/androidx/car/app/navigation/model/PlaceListNavigationTemplate.java
index 5e15393..17c4e8d 100644
--- a/car/app/app/src/main/java/androidx/car/app/navigation/model/PlaceListNavigationTemplate.java
+++ b/car/app/app/src/main/java/androidx/car/app/navigation/model/PlaceListNavigationTemplate.java
@@ -17,17 +17,22 @@
package androidx.car.app.navigation.model;
import static androidx.car.app.model.constraints.ActionsConstraints.ACTIONS_CONSTRAINTS_HEADER;
+import static androidx.car.app.model.constraints.ActionsConstraints.ACTIONS_CONSTRAINTS_MAP;
import static androidx.car.app.model.constraints.ActionsConstraints.ACTIONS_CONSTRAINTS_SIMPLE;
import static androidx.car.app.model.constraints.RowListConstraints.ROW_LIST_CONSTRAINTS_SIMPLE;
import static java.util.Objects.requireNonNull;
+import android.annotation.SuppressLint;
+
import androidx.annotation.Keep;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.car.app.Screen;
import androidx.car.app.SurfaceCallback;
import androidx.car.app.annotations.CarProtocol;
+import androidx.car.app.annotations.ExperimentalCarApi;
+import androidx.car.app.annotations.RequiresCarApi;
import androidx.car.app.model.Action;
import androidx.car.app.model.ActionStrip;
import androidx.car.app.model.CarText;
@@ -84,6 +89,12 @@
@Keep
@Nullable
private final ActionStrip mActionStrip;
+ @Keep
+ @Nullable
+ private final ActionStrip mMapActionStrip;
+ @Keep
+ @Nullable
+ private final PanModeDelegate mPanModeDelegate;
/**
* Returns the title of the template or {@code null} if not set.
@@ -117,6 +128,29 @@
}
/**
+ * Returns the map {@link ActionStrip} for this template or {@code null} if not set.
+ *
+ * @see Builder#setMapActionStrip(ActionStrip)
+ */
+ @ExperimentalCarApi
+ @RequiresCarApi(4)
+ @Nullable
+ public ActionStrip getMapActionStrip() {
+ return mMapActionStrip;
+ }
+
+ /**
+ * Returns the {@link PanModeDelegate} that should be called when the user interacts with
+ * pan mode on this template, or {@code null} if a {@link PanModeListener} was not set.
+ */
+ @ExperimentalCarApi
+ @RequiresCarApi(4)
+ @Nullable
+ public PanModeDelegate getPanModeDelegate() {
+ return mPanModeDelegate;
+ }
+
+ /**
* Returns whether the template is loading.
*
* @see Builder#setLoading(boolean)
@@ -144,7 +178,8 @@
@Override
public int hashCode() {
- return Objects.hash(mTitle, mIsLoading, mItemList, mHeaderAction, mActionStrip);
+ return Objects.hash(mTitle, mIsLoading, mItemList, mHeaderAction, mActionStrip,
+ mMapActionStrip, mPanModeDelegate == null);
}
@Override
@@ -161,7 +196,9 @@
&& Objects.equals(mTitle, otherTemplate.mTitle)
&& Objects.equals(mItemList, otherTemplate.mItemList)
&& Objects.equals(mHeaderAction, otherTemplate.mHeaderAction)
- && Objects.equals(mActionStrip, otherTemplate.mActionStrip);
+ && Objects.equals(mActionStrip, otherTemplate.mActionStrip)
+ && Objects.equals(mMapActionStrip, otherTemplate.mMapActionStrip)
+ && Objects.equals(mPanModeDelegate == null, otherTemplate.mPanModeDelegate == null);
}
PlaceListNavigationTemplate(Builder builder) {
@@ -170,6 +207,8 @@
mItemList = builder.mItemList;
mHeaderAction = builder.mHeaderAction;
mActionStrip = builder.mActionStrip;
+ mMapActionStrip = builder.mMapActionStrip;
+ mPanModeDelegate = builder.mPanModeDelegate;
}
/** Constructs an empty instance, used by serialization code. */
@@ -179,6 +218,8 @@
mItemList = null;
mHeaderAction = null;
mActionStrip = null;
+ mMapActionStrip = null;
+ mPanModeDelegate = null;
}
/** A builder of {@link PlaceListNavigationTemplate}. */
@@ -192,6 +233,10 @@
Action mHeaderAction;
@Nullable
ActionStrip mActionStrip;
+ @Nullable
+ ActionStrip mMapActionStrip;
+ @Nullable
+ PanModeDelegate mPanModeDelegate;
/**
* Sets the title of the template.
@@ -328,6 +373,57 @@
}
/**
+ * Sets an {@link ActionStrip} with a list of map-control related actions for this
+ * template, such as pan or zoom.
+ *
+ * <p>The host will draw the buttons in an area that is associated with map controls.
+ *
+ * <p>If the app does not include the {@link Action#PAN} button in this
+ * {@link ActionStrip}, the app will not receive the user input for panning gestures from
+ * {@link SurfaceCallback} methods, and the host will exit any previously activated pan
+ * mode.
+ *
+ * <h4>Requirements</h4>
+ *
+ * This template allows up to 4 {@link Action}s in its map {@link ActionStrip}. Only
+ * {@link Action}s with icons set via {@link Action.Builder#setIcon} are allowed.
+ *
+ * @throws IllegalArgumentException if {@code actionStrip} does not meet the template's
+ * requirements
+ * @throws NullPointerException if {@code actionStrip} is {@code null}
+ */
+ @ExperimentalCarApi
+ @RequiresCarApi(4)
+ @NonNull
+ public Builder setMapActionStrip(@NonNull ActionStrip actionStrip) {
+ ACTIONS_CONSTRAINTS_MAP.validateOrThrow(
+ requireNonNull(actionStrip).getActions());
+ mMapActionStrip = actionStrip;
+ return this;
+ }
+
+ /**
+ * Sets a {@link PanModeListener} that notifies when the user enters and exits
+ * the pan mode.
+ *
+ * <p>If the app does not include the {@link Action#PAN} button in the map
+ * {@link ActionStrip}, the app will not receive the user input for panning gestures from
+ * {@link SurfaceCallback} methods, and the host will exit any previously activated pan
+ * mode.
+ *
+ * @throws NullPointerException if {@code panModeListener} is {@code null}
+ */
+ @SuppressLint({"MissingGetterMatchingBuilder", "ExecutorRegistration"})
+ @ExperimentalCarApi
+ @RequiresCarApi(4)
+ @NonNull
+ public Builder setPanModeListener(@NonNull PanModeListener panModeListener) {
+ requireNonNull(panModeListener);
+ mPanModeDelegate = PanModeDelegateImpl.create(panModeListener);
+ return this;
+ }
+
+ /**
* Constructs the template defined by this builder.
*
* <h4>Requirements</h4>
diff --git a/car/app/app/src/main/java/androidx/car/app/navigation/model/RoutePreviewNavigationTemplate.java b/car/app/app/src/main/java/androidx/car/app/navigation/model/RoutePreviewNavigationTemplate.java
index 47d711d..5077063 100644
--- a/car/app/app/src/main/java/androidx/car/app/navigation/model/RoutePreviewNavigationTemplate.java
+++ b/car/app/app/src/main/java/androidx/car/app/navigation/model/RoutePreviewNavigationTemplate.java
@@ -17,17 +17,22 @@
package androidx.car.app.navigation.model;
import static androidx.car.app.model.constraints.ActionsConstraints.ACTIONS_CONSTRAINTS_HEADER;
+import static androidx.car.app.model.constraints.ActionsConstraints.ACTIONS_CONSTRAINTS_MAP;
import static androidx.car.app.model.constraints.ActionsConstraints.ACTIONS_CONSTRAINTS_SIMPLE;
import static androidx.car.app.model.constraints.RowListConstraints.ROW_LIST_CONSTRAINTS_ROUTE_PREVIEW;
import static java.util.Objects.requireNonNull;
+import android.annotation.SuppressLint;
+
import androidx.annotation.Keep;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.car.app.Screen;
import androidx.car.app.SurfaceCallback;
import androidx.car.app.annotations.CarProtocol;
+import androidx.car.app.annotations.ExperimentalCarApi;
+import androidx.car.app.annotations.RequiresCarApi;
import androidx.car.app.model.Action;
import androidx.car.app.model.ActionStrip;
import androidx.car.app.model.CarText;
@@ -97,6 +102,12 @@
@Keep
@Nullable
private final ActionStrip mActionStrip;
+ @Keep
+ @Nullable
+ private final ActionStrip mMapActionStrip;
+ @Keep
+ @Nullable
+ private final PanModeDelegate mPanModeDelegate;
/**
* Returns the title of the template or {@code null} if not set.
@@ -130,6 +141,29 @@
}
/**
+ * Returns the map {@link ActionStrip} for this template or {@code null} if not set.
+ *
+ * @see Builder#setMapActionStrip(ActionStrip)
+ */
+ @ExperimentalCarApi
+ @RequiresCarApi(4)
+ @Nullable
+ public ActionStrip getMapActionStrip() {
+ return mMapActionStrip;
+ }
+
+ /**
+ * Returns the {@link PanModeDelegate} that should be called when the user interacts with
+ * pan mode on this template, or {@code null} if a {@link PanModeListener} was not set.
+ */
+ @ExperimentalCarApi
+ @RequiresCarApi(4)
+ @Nullable
+ public PanModeDelegate getPanModeDelegate() {
+ return mPanModeDelegate;
+ }
+
+ /**
* Returns whether the template is loading.
*
* @see Builder#setLoading(boolean)
@@ -169,7 +203,7 @@
@Override
public int hashCode() {
return Objects.hash(mTitle, mIsLoading, mNavigateAction, mItemList, mHeaderAction,
- mActionStrip);
+ mActionStrip, mMapActionStrip, mPanModeDelegate == null);
}
@Override
@@ -187,7 +221,9 @@
&& Objects.equals(mNavigateAction, otherTemplate.mNavigateAction)
&& Objects.equals(mItemList, otherTemplate.mItemList)
&& Objects.equals(mHeaderAction, otherTemplate.mHeaderAction)
- && Objects.equals(mActionStrip, otherTemplate.mActionStrip);
+ && Objects.equals(mActionStrip, otherTemplate.mActionStrip)
+ && Objects.equals(mMapActionStrip, otherTemplate.mMapActionStrip)
+ && Objects.equals(mPanModeDelegate == null, otherTemplate.mPanModeDelegate == null);
}
RoutePreviewNavigationTemplate(Builder builder) {
@@ -197,6 +233,8 @@
mItemList = builder.mItemList;
mHeaderAction = builder.mHeaderAction;
mActionStrip = builder.mActionStrip;
+ mMapActionStrip = builder.mMapActionStrip;
+ mPanModeDelegate = builder.mPanModeDelegate;
}
/** Constructs an empty instance, used by serialization code. */
@@ -207,6 +245,8 @@
mItemList = null;
mHeaderAction = null;
mActionStrip = null;
+ mMapActionStrip = null;
+ mPanModeDelegate = null;
}
/** A builder of {@link RoutePreviewNavigationTemplate}. */
@@ -222,6 +262,10 @@
Action mHeaderAction;
@Nullable
ActionStrip mActionStrip;
+ @Nullable
+ ActionStrip mMapActionStrip;
+ @Nullable
+ PanModeDelegate mPanModeDelegate;
/**
* Sets the title of the template.
@@ -379,6 +423,57 @@
}
/**
+ * Sets an {@link ActionStrip} with a list of map-control related actions for this
+ * template, such as pan or zoom.
+ *
+ * <p>The host will draw the buttons in an area that is associated with map controls.
+ *
+ * <p>If the app does not include the {@link Action#PAN} button in this
+ * {@link ActionStrip}, the app will not receive the user input for panning gestures from
+ * {@link SurfaceCallback} methods, and the host will exit any previously activated pan
+ * mode.
+ *
+ * <h4>Requirements</h4>
+ *
+ * This template allows up to 4 {@link Action}s in its map {@link ActionStrip}. Only
+ * {@link Action}s with icons set via {@link Action.Builder#setIcon} are allowed.
+ *
+ * @throws IllegalArgumentException if {@code actionStrip} does not meet the template's
+ * requirements
+ * @throws NullPointerException if {@code actionStrip} is {@code null}
+ */
+ @ExperimentalCarApi
+ @RequiresCarApi(4)
+ @NonNull
+ public Builder setMapActionStrip(@NonNull ActionStrip actionStrip) {
+ ACTIONS_CONSTRAINTS_MAP.validateOrThrow(
+ requireNonNull(actionStrip).getActions());
+ mMapActionStrip = actionStrip;
+ return this;
+ }
+
+ /**
+ * Sets a {@link PanModeListener} that notifies when the user enters and exits
+ * the pan mode.
+ *
+ * <p>If the app does not include the {@link Action#PAN} button in the map
+ * {@link ActionStrip}, the app will not receive the user input for panning gestures from
+ * {@link SurfaceCallback} methods, and the host will exit any previously activated pan
+ * mode.
+ *
+ * @throws NullPointerException if {@code panModeListener} is {@code null}
+ */
+ @SuppressLint({"MissingGetterMatchingBuilder", "ExecutorRegistration"})
+ @ExperimentalCarApi
+ @RequiresCarApi(4)
+ @NonNull
+ public Builder setPanModeListener(@NonNull PanModeListener panModeListener) {
+ requireNonNull(panModeListener);
+ mPanModeDelegate = PanModeDelegateImpl.create(panModeListener);
+ return this;
+ }
+
+ /**
* Constructs the template defined by this builder.
*
* <h4>Requirements</h4>
diff --git a/car/app/app/src/test/java/androidx/car/app/navigation/model/PlaceListNavigationTemplateTest.java b/car/app/app/src/test/java/androidx/car/app/navigation/model/PlaceListNavigationTemplateTest.java
index 82764d7..fd43af8 100644
--- a/car/app/app/src/test/java/androidx/car/app/navigation/model/PlaceListNavigationTemplateTest.java
+++ b/car/app/app/src/test/java/androidx/car/app/navigation/model/PlaceListNavigationTemplateTest.java
@@ -52,6 +52,19 @@
private final DistanceSpan mDistanceSpan =
DistanceSpan.create(
Distance.create(/* displayDistance= */ 1, Distance.UNIT_KILOMETERS_P1));
+ private final ActionStrip mActionStrip =
+ new ActionStrip.Builder().addAction(TestUtils.createAction("test", null)).build();
+ private final ActionStrip mMapActionStrip =
+ new ActionStrip.Builder().addAction(
+ TestUtils.createAction(null, TestUtils.getTestCarIcon(
+ ApplicationProvider.getApplicationContext(),
+ "ic_test_1"))).build();
+
+ @Test
+ public void textButtonInMapActionStrip_throws() {
+ assertThrows(IllegalArgumentException.class,
+ () -> new PlaceListNavigationTemplate.Builder().setMapActionStrip(mActionStrip));
+ }
@Test
public void createInstance_emptyList_notLoading_Throws() {
@@ -205,10 +218,12 @@
.setItemList(itemList)
.setTitle(title)
.setActionStrip(actionStrip)
+ .setMapActionStrip(mMapActionStrip)
.build();
assertThat(template.getItemList()).isEqualTo(itemList);
assertThat(template.getActionStrip()).isEqualTo(actionStrip);
assertThat(template.getTitle().toString()).isEqualTo(title);
+ assertThat(template.getMapActionStrip()).isEqualTo(mMapActionStrip);
}
@Test
@@ -324,6 +339,8 @@
TestUtils.createItemListWithDistanceSpan(6, false, mDistanceSpan))
.setHeaderAction(Action.BACK)
.setActionStrip(new ActionStrip.Builder().addAction(Action.BACK).build())
+ .setMapActionStrip(mMapActionStrip)
+ .setPanModeListener((panModechanged) -> {})
.setTitle("title")
.build();
@@ -335,6 +352,8 @@
.setHeaderAction(Action.BACK)
.setActionStrip(
new ActionStrip.Builder().addAction(Action.BACK).build())
+ .setMapActionStrip(mMapActionStrip)
+ .setPanModeListener((panModechanged) -> {})
.setTitle("title")
.build());
}
@@ -398,6 +417,58 @@
}
@Test
+ public void notEquals_differentMapActionStrip() {
+ PlaceListNavigationTemplate template = new PlaceListNavigationTemplate.Builder()
+ .setTitle("Title")
+ .setItemList(
+ TestUtils.createItemListWithDistanceSpan(6, false, mDistanceSpan))
+ .setActionStrip(
+ mActionStrip)
+ .setMapActionStrip(mMapActionStrip)
+ .build();
+
+ assertThat(template)
+ .isNotEqualTo(
+ new PlaceListNavigationTemplate.Builder()
+ .setTitle("Title")
+ .setItemList(
+ TestUtils.createItemListWithDistanceSpan(6, false,
+ mDistanceSpan))
+ .setActionStrip(mActionStrip)
+ .setMapActionStrip(new ActionStrip.Builder().addAction(
+ TestUtils.createAction(null, TestUtils.getTestCarIcon(
+ ApplicationProvider.getApplicationContext(),
+ "ic_test_2"))).build())
+ .build());
+ }
+
+ @Test
+ public void notEquals_panModeListenerChange() {
+ PlaceListNavigationTemplate template = new PlaceListNavigationTemplate.Builder()
+ .setTitle("Title")
+ .setItemList(
+ TestUtils.createItemListWithDistanceSpan(6, false, mDistanceSpan))
+ .setActionStrip(
+ mActionStrip)
+ .setMapActionStrip(mMapActionStrip)
+ .setPanModeListener((panModechanged) -> {
+ })
+ .build();
+
+ assertThat(template)
+ .isNotEqualTo(
+ new PlaceListNavigationTemplate.Builder()
+ .setTitle("Title")
+ .setItemList(
+ TestUtils.createItemListWithDistanceSpan(6, false,
+ mDistanceSpan))
+ .setActionStrip(
+ mActionStrip)
+ .setMapActionStrip(mMapActionStrip)
+ .build());
+ }
+
+ @Test
public void notEquals_differentTitle() {
PlaceListNavigationTemplate template =
new PlaceListNavigationTemplate.Builder()
diff --git a/car/app/app/src/test/java/androidx/car/app/navigation/model/RoutePreviewNavigationTemplateTest.java b/car/app/app/src/test/java/androidx/car/app/navigation/model/RoutePreviewNavigationTemplateTest.java
index 302eec5..5705004 100644
--- a/car/app/app/src/test/java/androidx/car/app/navigation/model/RoutePreviewNavigationTemplateTest.java
+++ b/car/app/app/src/test/java/androidx/car/app/navigation/model/RoutePreviewNavigationTemplateTest.java
@@ -51,6 +51,13 @@
DistanceSpan.create(
Distance.create(/* displayDistance= */ 1, Distance.UNIT_KILOMETERS_P1));
private final Context mContext = ApplicationProvider.getApplicationContext();
+ private final ActionStrip mActionStrip =
+ new ActionStrip.Builder().addAction(TestUtils.createAction("test", null)).build();
+ private final ActionStrip mMapActionStrip =
+ new ActionStrip.Builder().addAction(
+ TestUtils.createAction(null, TestUtils.getTestCarIcon(
+ ApplicationProvider.getApplicationContext(),
+ "ic_test_1"))).build();
@Test
public void createInstance_emptyList_notLoading_Throws() {
@@ -135,6 +142,12 @@
}
@Test
+ public void textButtonInMapActionStrip_throws() {
+ assertThrows(IllegalArgumentException.class,
+ () -> new RoutePreviewNavigationTemplate.Builder().setMapActionStrip(mActionStrip));
+ }
+
+ @Test
public void createInstance() {
ItemList itemList = TestUtils.createItemListWithDistanceSpan(2, true, DISTANCE);
String title = "title";
@@ -145,6 +158,7 @@
.setNavigateAction(
new Action.Builder().setTitle("Navigate").setOnClickListener(() -> {
}).build())
+ .setMapActionStrip(mMapActionStrip)
.build();
assertThat(template.getItemList()).isEqualTo(itemList);
assertThat(template.getTitle().toString()).isEqualTo(title);
@@ -364,6 +378,9 @@
.setNavigateAction(
new Action.Builder().setTitle("drive").setOnClickListener(() -> {
}).build())
+ .setMapActionStrip(mMapActionStrip)
+ .setPanModeListener((panModechanged) -> {
+ })
.build();
assertThat(template)
@@ -379,6 +396,9 @@
new Action.Builder().setTitle("drive").setOnClickListener(
() -> {
}).build())
+ .setMapActionStrip(mMapActionStrip)
+ .setPanModeListener((panModechanged) -> {
+ })
.build());
}
@@ -459,6 +479,70 @@
}
@Test
+ public void notEquals_differentMapActionStrip() {
+ RoutePreviewNavigationTemplate template =
+ new RoutePreviewNavigationTemplate.Builder()
+ .setTitle("Title")
+ .setItemList(TestUtils.createItemListWithDistanceSpan(2, true, DISTANCE))
+ .setActionStrip(new ActionStrip.Builder().addAction(Action.BACK).build())
+ .setNavigateAction(
+ new Action.Builder().setTitle("drive").setOnClickListener(() -> {
+ }).build())
+ .setMapActionStrip(mMapActionStrip)
+ .build();
+
+ assertThat(template)
+ .isNotEqualTo(
+ new RoutePreviewNavigationTemplate.Builder()
+ .setTitle("Title")
+ .setItemList(
+ TestUtils.createItemListWithDistanceSpan(2, true, DISTANCE))
+ .setActionStrip(
+ new ActionStrip.Builder().addAction(
+ Action.APP_ICON).build())
+ .setNavigateAction(
+ new Action.Builder().setTitle("drive").setOnClickListener(
+ () -> {
+ }).build())
+ .setMapActionStrip(new ActionStrip.Builder().addAction(
+ TestUtils.createAction(null, TestUtils.getTestCarIcon(
+ ApplicationProvider.getApplicationContext(),
+ "ic_test_2"))).build())
+ .build());
+ }
+
+ @Test
+ public void notEquals_panModeListenerChange() {
+ RoutePreviewNavigationTemplate template =
+ new RoutePreviewNavigationTemplate.Builder()
+ .setTitle("Title")
+ .setItemList(TestUtils.createItemListWithDistanceSpan(2, true, DISTANCE))
+ .setActionStrip(new ActionStrip.Builder().addAction(Action.BACK).build())
+ .setNavigateAction(
+ new Action.Builder().setTitle("drive").setOnClickListener(() -> {
+ }).build())
+ .setMapActionStrip(mMapActionStrip)
+ .setPanModeListener((panModechanged) -> {
+ })
+ .build();
+
+ assertThat(template)
+ .isNotEqualTo(
+ new RoutePreviewNavigationTemplate.Builder()
+ .setTitle("Title")
+ .setItemList(
+ TestUtils.createItemListWithDistanceSpan(2, true, DISTANCE))
+ .setActionStrip(
+ new ActionStrip.Builder().addAction(Action.BACK).build())
+ .setNavigateAction(
+ new Action.Builder().setTitle("drive").setOnClickListener(
+ () -> {
+ }).build())
+ .setMapActionStrip(mMapActionStrip)
+ .build());
+ }
+
+ @Test
public void notEquals_differentTitle() {
SpannableString title = new SpannableString("Title");
title.setSpan(DISTANCE, 0, 1, 0);