RecycleView set the top divider (record a pit)

As you all know, if you want to set the divider for RecycleView, you can override RecycleView.itemdecoration

During the project, I met a requirement: there is a gray interval at the top of RecycleView. I came up with a method to set the dividing line for RecycleView. Of course, only the first Item is set, and it is at the top.

public class MyDividerItemDecoration extends RecyclerView.ItemDecoration {

    private Drawable mDivider;

    /**
     * Custom divider will be used
     */
    public MyDividerItemDecoration(Context context, int resId) {
        mDivider = ContextCompat.getDrawable(context, resId);
    }

    @Override
    public void getItemOffsets(Rect outRect, View view, RecyclerView parent, 
RecyclerView.State state) {
super.getItemOffsets(outRect, view, parent, state); RecyclerView.LayoutManager layoutManager = parent.getLayoutManager(); //Because the top split line is drawn, the item Move down the corresponding distance
//Note here that it is necessary to determine what layout the RecycleView is, and if it is a linear layout in the vertical direction (not considered here in the horizontal direction)
//, then you need to move the first Item down, the distance is the height of the split line, because the split line will occupy the space of the Item
//If it is a grid layout, all items in the first row need to be moved down to the corresponding height
if (layoutManager instanceof LinearLayoutManager) { if (parent.getChildAdapterPosition(view) == 0) { outRect.set(0, mDivider.getIntrinsicHeight(), 0, 0); } } if (layoutManager instanceof GridLayoutManager) { if (parent.getChildAdapterPosition(view) >= 0 &&
parent.getChildAdapterPosition(view) < getSpanCount(parent)) { outRect.set(0, mDivider.getIntrinsicHeight(), 0, 0); } } } @Override public void onDrawOver(Canvas c, RecyclerView parent, RecyclerView.State state) { //Draw split line int left = 0; int right = parent.getWidth(); View child = parent.getChildAt(0); RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child.getLayoutParams(); //Cannot be set directly top = 0;Because in this way, the separation line will not follow the movement, because top = 0,It's absolute position,
//So it should be set as the relative position of the child view
//So you can slide with it.
//The top coordinate of the child, subtracting the value of the set margin ﹣ top, and then subtracting the height that the child glides to make room for the split line,
//So that the split line is at the top
int top = child.getTop() - params.topMargin - mDivider.getIntrinsicHeight(); int bottom; bottom = top + mDivider.getIntrinsicHeight(); mDivider.setBounds(left, top, right, bottom); mDivider.draw(c); } private int getSpanCount(RecyclerView parent) { // Column number int spanCount = -1; RecyclerView.LayoutManager layoutManager = parent.getLayoutManager(); if (layoutManager instanceof GridLayoutManager) { spanCount = ((GridLayoutManager) layoutManager).getSpanCount(); } else if (layoutManager instanceof StaggeredGridLayoutManager) { spanCount = ((StaggeredGridLayoutManager) layoutManager) .getSpanCount(); } else if (layoutManager instanceof LinearLayoutManager) { spanCount = layoutManager.getItemCount(); } return spanCount; }

You can draw split lines in the onDrawOver method.

There is a pit to pay attention to here. After debugging for a long time, it was finally found that it was hard.

In onDrawOver, I set top = 0 at first, because the drawing is at the top. The result is a phenomenon where the top divider stays at the top and doesn't move with it. Finally, it is changed to int top = child. Gettop() - params. Topmargin - mdivider. Getinsideheight(); to succeed. Why?

Because directly write top = 0; this is the absolute position. To make the split line slide with it, you need to use the relative position, relative to the item position, so that you can slide with the item.

 

Call:

recyclerView.addItemDecoration(new MyDividerItemDecoration(this, R.drawable.item_decoration));

The code of item_decoration is as follows:

<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="rectangle">
    <size android:height="10dp" />
    <solid android:color="@color/comic_gray_bg" />
</shape>

Tags: Android

Posted on Sun, 05 Jan 2020 16:02:17 -0800 by Chris12345