Skip to content

Commit

Permalink
[Divider] Added attribute in MaterialDividerItemDecoration to remove …
Browse files Browse the repository at this point in the history
…item decoration from last recycler view item.

PiperOrigin-RevId: 416890397
  • Loading branch information
leticiarossi committed Dec 20, 2021
1 parent 7665730 commit 9416b2c
Show file tree
Hide file tree
Showing 6 changed files with 61 additions and 9 deletions.
27 changes: 19 additions & 8 deletions docs/components/Divider.md
Expand Up @@ -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:

Expand All @@ -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:

Expand All @@ -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
Expand All @@ -113,12 +123,13 @@ precautions for the divider.

### Dividers attributes

Element | Attribute | Related method(s) | Default value
--------------- | ----------------------- | ------------------------------------------------------------------------------------ | -------------
**Thickness** | `app:dividerThickness` | `setDividerThickness`<br/>`setDividerThicknessResource`<br/>`getDividerThickness` | `1dp` for the regular divider <br/> `8dp` for the heavy divider
**Color** | `app:dividerColor` | `setDividerColor`<br/>`setDividerColorResource`<br/>`getDividerColor` | `colorOutline`
**Start inset** | `app:dividerInsetStart` | `setDividerInsetStart`<br/>`setDividerInsetStartResource`<br/>`getDividerInsetStart` | `0dp`
**End inset** | `app:dividerInsetEnd` | `setDividerInsetEnd`<br/>`setDividerInsetEndResource`<br/>`getDividerInsetEnd` | `0dp`
Element | Attribute | Related method(s) | Default value
----------------------- | ---------------------- | ------------------------------------------------------------------------------------ | -------------
**Thickness** | `app:dividerThickness` | `setDividerThickness`<br/>`setDividerThicknessResource`<br/>`getDividerThickness` | `1dp` for the regular divider <br/> `8dp` for the heavy divider
**Color** | `app:dividerColor` | `setDividerColor`<br/>`setDividerColorResource`<br/>`getDividerColor` | `colorOutline`
**Start inset** | `app:dividerInsetStart` | `setDividerInsetStart`<br/>`setDividerInsetStartResource`<br/>`getDividerInsetStart` | `0dp`
**End inset** | `app:dividerInsetEnd` | `setDividerInsetEnd`<br/>`setDividerInsetEndResource`<br/>`getDividerInsetEnd` | `0dp`
**Last item decorated** | `app:lastItemDecorated` | `setLastItemDecorated`<br/>`isLastItemDecorated` | `true`

### Styles

Expand Down
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Expand Up @@ -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();

Expand Down Expand Up @@ -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();

Expand Down Expand Up @@ -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) {
Expand Down Expand Up @@ -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.
Expand Down
Expand Up @@ -20,6 +20,7 @@
<public name="dividerThickness" type="attr"/>
<public name="dividerInsetStart" type="attr"/>
<public name="dividerInsetEnd" type="attr"/>
<public name="lastItemDecorated" type="attr"/>
<public name="Widget.MaterialComponents.MaterialDivider" type="style"/>
<public name="Widget.Material3.MaterialDivider" type="style"/>
<public name="Widget.Material3.MaterialDivider.Heavy" type="style"/>
Expand Down
Expand Up @@ -33,5 +33,8 @@
<attr name="dividerInsetEnd"/>
<!-- End indent of the divider. -->
<attr name="dividerInsetStart"/>
<!-- Whether the MaterialDividerItemDecoration class should draw a divider
after the last item of the recycler view. True by default. -->
<attr name="lastItemDecorated" format="boolean"/>
</declare-styleable>
</resources>
Expand Up @@ -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);
Expand Down

0 comments on commit 9416b2c

Please sign in to comment.