Add ability to specify the scrollbar container width.
The scrollbar is centered within this width.
Test: unit tests and test on sample app.
Bug: 72118903
Change-Id: I621448cc6c097b09485546880aed14f143f5fc0f
diff --git a/car/res/values/attrs.xml b/car/res/values/attrs.xml
index 4930e1b..6b6c44b 100644
--- a/car/res/values/attrs.xml
+++ b/car/res/values/attrs.xml
@@ -50,6 +50,10 @@
<attr name="scrollBarEnabled" format="boolean" />
<!-- The top margin before the scroll bar is drawn. -->
<attr name="scrollBarTopMargin" format="dimension" />
+ <!-- The width of the container that will hold the scrollbar. The scrollbar is centered
+ within this value. If this value is not explicitly set, the scrollbar centers itself
+ within the car_margin value. -->
+ <attr name="scrollBarContainerWidth" format="dimension" />
<!-- Whether or not to show a diving line between each item of the list. -->
<attr name="showPagedListViewDivider" format="boolean" />
<!-- An optional id that specifies a child View whose starting edge will be used to
diff --git a/car/src/main/java/androidx/car/widget/PagedListView.java b/car/src/main/java/androidx/car/widget/PagedListView.java
index cc4b4fa..2831fa2 100644
--- a/car/src/main/java/androidx/car/widget/PagedListView.java
+++ b/car/src/main/java/androidx/car/widget/PagedListView.java
@@ -40,6 +40,7 @@
import android.util.SparseArray;
import android.view.LayoutInflater;
import android.view.View;
+import android.view.ViewGroup;
import android.widget.FrameLayout;
import androidx.car.R;
@@ -341,6 +342,13 @@
params.setMarginStart(0);
}
+ if (a.hasValue(R.styleable.PagedListView_scrollBarContainerWidth)) {
+ int carMargin = getResources().getDimensionPixelSize(R.dimen.car_margin);
+ int scrollBarContainerWidth = a.getDimensionPixelSize(
+ R.styleable.PagedListView_scrollBarContainerWidth, carMargin);
+ setScrollBarContainerWidth(scrollBarContainerWidth);
+ }
+
setDayNightStyle(DayNightStyle.AUTO);
a.recycle();
}
@@ -407,6 +415,18 @@
}
/**
+ * Sets the width of the container that holds the scrollbar. The scrollbar will be centered
+ * within this width.
+ *
+ * @param width The width of the scrollbar container.
+ */
+ public void setScrollBarContainerWidth(int width) {
+ ViewGroup.LayoutParams layoutParams = mScrollBarView.getLayoutParams();
+ layoutParams.width = width;
+ mScrollBarView.requestLayout();
+ }
+
+ /**
* Sets the top margin above the scroll bar. By default, this margin is 0.
*
* @param topMargin The top margin.
@@ -414,7 +434,7 @@
public void setScrollBarTopMargin(int topMargin) {
MarginLayoutParams params = (MarginLayoutParams) mScrollBarView.getLayoutParams();
params.topMargin = topMargin;
- requestLayout();
+ mScrollBarView.requestLayout();
}
@NonNull
diff --git a/car/tests/src/androidx/car/widget/PagedListViewTest.java b/car/tests/src/androidx/car/widget/PagedListViewTest.java
index 8579fd5..fe56a71 100644
--- a/car/tests/src/androidx/car/widget/PagedListViewTest.java
+++ b/car/tests/src/androidx/car/widget/PagedListViewTest.java
@@ -520,6 +520,36 @@
assertThat(mPagedListView.getRecyclerView().getPaddingEnd(), is(equalTo(gutterSize)));
}
+ @Test
+ public void setDefaultScrollBarContainerWidth() {
+ if (!isAutoDevice()) {
+ return;
+ }
+
+ // Just need enough items to ensure the scroll bar is showing.
+ setUpPagedListView(ITEMS_PER_PAGE * 10);
+
+ Resources res = InstrumentationRegistry.getContext().getResources();
+ int defaultWidth = res.getDimensionPixelSize(R.dimen.car_margin);
+
+ onView(withId(R.id.paged_scroll_view)).check(matches(withWidth(defaultWidth)));
+ }
+
+ @Test
+ public void testSetScrollBarContainerWidth() {
+ if (!isAutoDevice()) {
+ return;
+ }
+
+ // Just need enough items to ensure the scroll bar is showing.
+ setUpPagedListView(ITEMS_PER_PAGE * 10);
+
+ int scrollBarContainerWidth = 120;
+ mPagedListView.setScrollBarContainerWidth(scrollBarContainerWidth);
+
+ onView(withId(R.id.paged_scroll_view)).check(matches(withWidth(scrollBarContainerWidth)));
+ }
+
private static String itemText(int index) {
return "Data " + index;
}
@@ -652,4 +682,24 @@
}
};
}
+
+ /**
+ * Returns a matcher that matches {@link View}s that have the given width.
+ *
+ * @param width The width to match to.
+ */
+ @NonNull
+ public static Matcher<View> withWidth(int width) {
+ return new TypeSafeMatcher<View>() {
+ @Override
+ public void describeTo(Description description) {
+ description.appendText("with width: " + width);
+ }
+
+ @Override
+ public boolean matchesSafely(View view) {
+ return width == view.getLayoutParams().width;
+ }
+ };
+ }
}