Add a 'gutter' attribute for specifying list item margins.
The gutter defaults to 'BOTH' and we also deprecate offsetScrollBar and
listEndMargin at the same time.
Test: build and run with a test app.
Bug: 69866647
Change-Id: I6b49a1b0b299c194643b288f52ccf2126ead2b9c
diff --git a/car/res/values/attrs.xml b/car/res/values/attrs.xml
index 0ba8f55..01ed95f 100644
--- a/car/res/values/attrs.xml
+++ b/car/res/values/attrs.xml
@@ -28,8 +28,24 @@
<!-- Set to true/false to offset rows as they slide off screen. Defaults to true -->
<attr name="offsetRows" format="boolean" />
<!-- Whether or not to offset the list view by the width of scroll bar. Setting this to
- true will ensure that any views within the list will not overlap the scroll bar. -->
+ true will ensure that any views within the list will not overlap the scroll bar.
+ Deprecated: use gutter instead. If gutter is specified, this value is ignored.-->
<attr name="offsetScrollBar" format="boolean" />
+ <!-- Whether to include a gutter to the start, end or both sides of the list view items.
+ The gutter width will be the width of the scrollbar, and by default will be set to
+ both. -->
+ <attr name="gutter" format="enum">
+ <!-- No gutter on either side, the list view items will extend the full width of the
+ PagedListView. -->
+ <enum name="none" value="0" />
+ <!-- Include a gutter on the start side only (i.e. the side with the scrollbar). -->
+ <enum name="start" value="1" />
+ <!-- Include a gutter on the end side only (i.e. the opposite side to the
+ scrollbar). -->
+ <enum name="end" value="2" />
+ <!-- Include a gutter on both sides of the list view items. -->
+ <enum name="both" value="3" />
+ </attr>
<!-- Whether to display the scrollbar or not. Defaults to true. -->
<attr name="scrollBarEnabled" format="boolean" />
<!-- Whether or not to show a diving line between each item of the list. -->
@@ -43,7 +59,8 @@
<!-- A starting margin before the drawing of the dividing line. This margin will be an
offset from the view specified by "alignDividerStartTo" if given. -->
<attr name="dividerStartMargin" format="dimension" />
- <!-- The width of the margin on the right side of the list -->
+ <!-- The width of the margin on the right side of the list.
+ Deprecated: use gutter instead. If gutter is specified, this value is ignored.-->
<attr name="listEndMargin" format="dimension" />
<!-- An optional spacing between items in the list -->
<attr name="itemSpacing" format="dimension" />
diff --git a/car/src/main/java/android/support/car/widget/PagedListView.java b/car/src/main/java/android/support/car/widget/PagedListView.java
index 67a6247..d815f09 100644
--- a/car/src/main/java/android/support/car/widget/PagedListView.java
+++ b/car/src/main/java/android/support/car/widget/PagedListView.java
@@ -29,6 +29,7 @@
import android.os.Parcel;
import android.os.Parcelable;
import android.support.annotation.IdRes;
+import android.support.annotation.IntDef;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.annotation.RestrictTo;
@@ -119,6 +120,39 @@
}
/**
+ * The possible values for @{link #setGutter}. The default value is actually
+ * {@link Gutter#BOTH}.
+ */
+ @IntDef({
+ Gutter.NONE,
+ Gutter.START,
+ Gutter.END,
+ Gutter.BOTH,
+ })
+ public @interface Gutter {
+ /**
+ * No gutter on either side of the list items. The items will span the full width of the
+ * {@link PagedListView}.
+ */
+ int NONE = 0;
+
+ /**
+ * Include a gutter only on the start side (that is, the same side as the scroll bar).
+ */
+ int START = 1;
+
+ /**
+ * Include a gutter only on the end side (that is, the opposite side of the scroll bar).
+ */
+ int END = 2;
+
+ /**
+ * Include a gutter on both sides of the list items. This is the default behaviour.
+ */
+ int BOTH = 3;
+ }
+
+ /**
* Interface for a {@link android.support.v7.widget.RecyclerView.Adapter} to set the position
* offset for the adapter to load the data.
*
@@ -167,14 +201,17 @@
mRecyclerView.getRecycledViewPool().setMaxRecycledViews(0, 12);
mRecyclerView.setItemAnimator(new CarItemAnimator(mLayoutManager));
- boolean offsetScrollBar = a.getBoolean(R.styleable.PagedListView_offsetScrollBar, false);
- if (offsetScrollBar) {
- MarginLayoutParams params = (MarginLayoutParams) mRecyclerView.getLayoutParams();
- params.setMarginStart(getResources().getDimensionPixelSize(
- R.dimen.car_margin));
- params.setMarginEnd(
- a.getDimensionPixelSize(R.styleable.PagedListView_listEndMargin, 0));
- mRecyclerView.setLayoutParams(params);
+ if (a.hasValue(R.styleable.PagedListView_gutter)) {
+ int gutter = a.getInt(R.styleable.PagedListView_gutter, Gutter.BOTH);
+ setGutter(gutter);
+ } else if (a.hasValue(R.styleable.PagedListView_offsetScrollBar)) {
+ boolean offsetScrollBar =
+ a.getBoolean(R.styleable.PagedListView_offsetScrollBar, false);
+ if (offsetScrollBar) {
+ setGutter(Gutter.START);
+ }
+ } else {
+ setGutter(Gutter.BOTH);
}
if (a.getBoolean(R.styleable.PagedListView_showPagedListViewDivider, true)) {
@@ -286,6 +323,31 @@
return mLayoutManager.getPosition(v);
}
+ /**
+ * Set the gutter to the specified value.
+ *
+ * The gutter is the space to the start/end of the list view items and will be equal in size
+ * to the scroll bars. By default, there is a gutter to both the left and right of the list
+ * view items, to account for the scroll bar.
+ *
+ * @param gutter A {@link Gutter} value that identifies which sides to apply the gutter to.
+ */
+ public void setGutter(@Gutter int gutter) {
+ int startPadding = 0;
+ int endPadding = 0;
+ if ((gutter & Gutter.START) != 0) {
+ startPadding = getResources().getDimensionPixelSize(R.dimen.car_margin);
+ }
+ if ((gutter & Gutter.END) != 0) {
+ endPadding = getResources().getDimensionPixelSize(R.dimen.car_margin);
+ }
+ mRecyclerView.setPaddingRelative(startPadding, 0, endPadding, 0);
+
+ // If there's a gutter, set ClipToPadding to false so that CardView's shadow will still
+ // appear outside of the padding.
+ mRecyclerView.setClipToPadding(startPadding == 0 && endPadding == 0);
+ }
+
@NonNull
public CarRecyclerView getRecyclerView() {
return mRecyclerView;