diff --git a/docs/components/Divider.md b/docs/components/Divider.md index 2a06761a54b..c71090abfc6 100644 --- a/docs/components/Divider.md +++ b/docs/components/Divider.md @@ -83,7 +83,7 @@ to a `DividerItemDecoration`, that can be used as a divider between items of a A list with full-bleed dividers is displayed below: -![Vertical list of five items with gray dividers between each item](assets/dividers/divider_itemdecoration.png) +![Vertical list of five items with five gray dividers after each item](assets/dividers/divider_itemdecoration.png) In code: @@ -95,7 +95,7 @@ recyclerView.addItemDecoration(divider) By default, dividers will be full-bleed. To achieve the look of an inset or middle divider: -![Vertical list of five items with gray dividers that have a start inset](assets/dividers/divider_itemdecoration_inset.png) +![Vertical list of five items with five gray dividers that have a start inset](assets/dividers/divider_itemdecoration_inset.png) In code: @@ -104,6 +104,16 @@ divider.setDividerInsetStart(insetStart) divider.setDividerInsetEnd(insetEnd) ``` +Optionally, you can hide the last divider of a list: + +![Vertical list of five items with four gray dividers](assets/dividers/divider_itemdecoration_hiddendivider.png) + +In code: + +```kt +divider.setLastItemDecorated(false) +``` + ### Making dividers accessible The divider is a decorative element. There are no special accessibility @@ -113,12 +123,13 @@ precautions for the divider. ### Dividers attributes -Element | Attribute | Related method(s) | Default value ---------------- | ----------------------- | ------------------------------------------------------------------------------------ | ------------- -**Thickness** | `app:dividerThickness` | `setDividerThickness`
`setDividerThicknessResource`
`getDividerThickness` | `1dp` for the regular divider
`8dp` for the heavy divider -**Color** | `app:dividerColor` | `setDividerColor`
`setDividerColorResource`
`getDividerColor` | `colorOutline` -**Start inset** | `app:dividerInsetStart` | `setDividerInsetStart`
`setDividerInsetStartResource`
`getDividerInsetStart` | `0dp` -**End inset** | `app:dividerInsetEnd` | `setDividerInsetEnd`
`setDividerInsetEndResource`
`getDividerInsetEnd` | `0dp` +Element | Attribute | Related method(s) | Default value +----------------------- | ---------------------- | ------------------------------------------------------------------------------------ | ------------- +**Thickness** | `app:dividerThickness` | `setDividerThickness`
`setDividerThicknessResource`
`getDividerThickness` | `1dp` for the regular divider
`8dp` for the heavy divider +**Color** | `app:dividerColor` | `setDividerColor`
`setDividerColorResource`
`getDividerColor` | `colorOutline` +**Start inset** | `app:dividerInsetStart` | `setDividerInsetStart`
`setDividerInsetStartResource`
`getDividerInsetStart` | `0dp` +**End inset** | `app:dividerInsetEnd` | `setDividerInsetEnd`
`setDividerInsetEndResource`
`getDividerInsetEnd` | `0dp` +**Last item decorated** | `app:lastItemDecorated` | `setLastItemDecorated`
`isLastItemDecorated` | `true` ### Styles diff --git a/docs/components/assets/dividers/divider_itemdecoration_hiddendivider.png b/docs/components/assets/dividers/divider_itemdecoration_hiddendivider.png new file mode 100644 index 00000000000..4348f2d2eef Binary files /dev/null and b/docs/components/assets/dividers/divider_itemdecoration_hiddendivider.png differ diff --git a/lib/java/com/google/android/material/divider/MaterialDividerItemDecoration.java b/lib/java/com/google/android/material/divider/MaterialDividerItemDecoration.java index 7dca340d050..8aea0acdf97 100644 --- a/lib/java/com/google/android/material/divider/MaterialDividerItemDecoration.java +++ b/lib/java/com/google/android/material/divider/MaterialDividerItemDecoration.java @@ -66,6 +66,7 @@ public class MaterialDividerItemDecoration extends ItemDecoration { private int orientation; private int insetStart; private int insetEnd; + private boolean lastItemDecorated; private final Rect tempRect = new Rect(); @@ -95,6 +96,8 @@ public MaterialDividerItemDecoration( insetStart = attributes.getDimensionPixelOffset(R.styleable.MaterialDivider_dividerInsetStart, 0); insetEnd = attributes.getDimensionPixelOffset(R.styleable.MaterialDivider_dividerInsetEnd, 0); + lastItemDecorated = + attributes.getBoolean(R.styleable.MaterialDivider_lastItemDecorated, true); attributes.recycle(); @@ -259,6 +262,27 @@ public int getDividerInsetEnd() { return insetEnd; } + /** + * Sets whether the class should draw a divider after the last item of a {@link RecyclerView}. + * + * @param lastItemDecorated whether there's a divider after the last item of a recycler view. + * @see #isLastItemDecorated() + * @attr ref com.google.android.material.R.styleable#MaterialDivider_lastItemDecorated + */ + public void setLastItemDecorated(boolean lastItemDecorated) { + this.lastItemDecorated = lastItemDecorated; + } + + /** + * Whether there's a divider after the last item of a {@link RecyclerView}. + * + * @see #setLastItemDecorated(boolean) + * @attr ref com.google.android.material.R.styleable#MaterialDivider_shouldDecorateLastItem + */ + public boolean isLastItemDecorated() { + return lastItemDecorated; + } + @Override public void onDraw( @NonNull Canvas canvas, @NonNull RecyclerView parent, @NonNull RecyclerView.State state) { @@ -294,7 +318,8 @@ private void drawForVerticalOrientation(@NonNull Canvas canvas, @NonNull Recycle right -= isRtl ? insetStart : insetEnd; int childCount = parent.getChildCount(); - for (int i = 0; i < childCount; i++) { + int dividerCount = lastItemDecorated ? childCount : childCount - 1; + for (int i = 0; i < dividerCount; i++) { View child = parent.getChildAt(i); parent.getDecoratedBoundsWithMargins(child, tempRect); // Take into consideration any translationY added to the view. diff --git a/lib/java/com/google/android/material/divider/res-public/values/public.xml b/lib/java/com/google/android/material/divider/res-public/values/public.xml index 9cd89621831..7ed45fbe344 100644 --- a/lib/java/com/google/android/material/divider/res-public/values/public.xml +++ b/lib/java/com/google/android/material/divider/res-public/values/public.xml @@ -20,6 +20,7 @@ + diff --git a/lib/java/com/google/android/material/divider/res/values/attrs.xml b/lib/java/com/google/android/material/divider/res/values/attrs.xml index d04fc76d083..15e117362ce 100644 --- a/lib/java/com/google/android/material/divider/res/values/attrs.xml +++ b/lib/java/com/google/android/material/divider/res/values/attrs.xml @@ -33,5 +33,8 @@ + + diff --git a/lib/javatests/com/google/android/material/divider/MaterialDividerItemDecorationTest.java b/lib/javatests/com/google/android/material/divider/MaterialDividerItemDecorationTest.java index 228a5dc7e5a..df036e65c01 100644 --- a/lib/javatests/com/google/android/material/divider/MaterialDividerItemDecorationTest.java +++ b/lib/javatests/com/google/android/material/divider/MaterialDividerItemDecorationTest.java @@ -127,6 +127,18 @@ public void setDividerInsetEndResource_succeeds() { assertThat(divider.getDividerInsetEnd()).isEqualTo(2); } + @Test + public void isLastItemDecorated_isTrueByDefault() { + assertThat(divider.isLastItemDecorated()).isTrue(); + } + + @Test + public void setLastItemNotDecorated_succeeds() { + divider.setLastItemDecorated(false); + + assertThat(divider.isLastItemDecorated()).isFalse(); + } + @Test public void getItemOffsets_verticalOrientation_returnsCorrectRect() { divider.getItemOffsets(rect, /* view= */ null, recyclerView, state);