Android 自定义RecyclerView.ItemDecoration(GridLayoutManager布局下)

为GridLayoutManager的RecyclerView自定义ItemDecoration分隔符。

效果如下:

这里写图片描述

Item布局xml:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
              android:layout_width="match_parent"
              android:layout_height="wrap_content"
              android:gravity="center_horizontal"
              android:orientation="vertical"
              android:paddingBottom="12dp"
              android:paddingTop="11dp">

    <TextView
        android:id="@+id/metalNameTextView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="现货黄金"
        android:textColor="#333333"
        android:textSize="16sp"/>

    <TextView
        android:id="@+id/metalSellTextView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginBottom="2dp"
        android:layout_marginTop="2dp"
        android:text="1250.68"
        android:textColor="#36BE32"
        android:textSize="18sp"/>

    <LinearLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:orientation="horizontal">

        <TextView
            android:id="@+id/metalBuyTextView"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginRight="4dp"
            android:text="-4.18"
            android:textColor="#36BE32"
            android:textSize="12sp"/>

        <TextView
            android:id="@+id/metalPercentTextView"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="-0.23%"
            android:textColor="#36BE32"
            android:textSize="12sp"/>
    </LinearLayout>
</LinearLayout>

divider_decoration:

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
    <gradient
        android:centerColor="#ff00ff00"
        android:endColor="#ff0000ff"
        android:startColor="#ffff0000"
        android:type="linear"/>
    <size android:height="4dp" android:width="4dp"/>
</shape>

自定义DividerItemDecoration:

public class DividerItemDecoration extends RecyclerView.ItemDecoration
{
    private Context mContext;
    private Drawable mDivider;

    public DividerItemDecoration(Context context)
    {
        this.mContext = context;
        mDivider = context.getResources().getDrawable(R.drawable.divider_decoration);
    }

    @Override
    public void onDraw(Canvas c, RecyclerView parent, RecyclerView.State state)
    {
        drawHorizontal(c, parent);
        drawVertical(c, parent);
    }

    //列数
    private int getSpanCount(RecyclerView parent)
    {
        int spanCount = -1;
        LayoutManager layoutManager = parent.getLayoutManager();
        if (layoutManager instanceof GridLayoutManager)
        {
            spanCount = ((GridLayoutManager) layoutManager).getSpanCount();
        }
        return spanCount;
    }

    //画横线
    public void drawHorizontal(Canvas c, RecyclerView parent)
    {
        int childCount = parent.getChildCount();
        for (int i = 0; i < childCount; i++)
        {
            final View child = parent.getChildAt(i);
            final RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child
                    .getLayoutParams();

            if (isFirstColum(parent, i, getSpanCount(parent), childCount))//如果是第一列
            {
                final int left = child.getLeft() + dip2px(15);
                final int right = child.getRight() + params.rightMargin
                        + mDivider.getIntrinsicWidth();
                final int top = child.getBottom() + params.bottomMargin;
                final int bottom = top + mDivider.getIntrinsicHeight();
                mDivider.setBounds(left, top, right, bottom);
                mDivider.draw(c);
            } else if (isLastColum(parent, i, getSpanCount(parent), childCount))//如果是最后一列
            {
                final int left = child.getLeft();
                final int right = child.getRight() - dip2px(15);
                final int top = child.getBottom() + params.bottomMargin;
                final int bottom = top + mDivider.getIntrinsicHeight();
                mDivider.setBounds(left, top, right, bottom);
                mDivider.draw(c);
            } else
            {
                final int left = child.getLeft();
                final int right = child.getRight() + mDivider.getIntrinsicWidth();
                final int top = child.getBottom() + params.bottomMargin;
                final int bottom = top + mDivider.getIntrinsicHeight();
                mDivider.setBounds(left, top, right, bottom);
                mDivider.draw(c);
            }
        }
    }

    //画竖线
    public void drawVertical(Canvas c, RecyclerView parent)
    {
        final int childCount = parent.getChildCount();
        for (int i = 0; i < childCount; i++)
        {
            final View child = parent.getChildAt(i);

            final RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child
                    .getLayoutParams();

            if (i < getSpanCount(parent))//如果是第一行
            {
                final int top = child.getTop() + child.getPaddingTop();
                final int bottom = child.getBottom();
                final int left = child.getRight() + params.rightMargin;
                final int right = left + mDivider.getIntrinsicWidth();
                mDivider.setBounds(left, top, right, bottom);
                mDivider.draw(c);
            } else if (isLastRaw(parent, i, getSpanCount(parent), childCount))//如果是最后一行
            {
                final int top = child.getTop();
                final int bottom = child.getBottom() - child.getPaddingBottom();
                final int left = child.getRight() + params.rightMargin;
                final int right = left + mDivider.getIntrinsicWidth();
                mDivider.setBounds(left, top, right, bottom);
                mDivider.draw(c);
            } else
            {
                final int top = child.getTop();
                final int bottom = child.getBottom();
                final int left = child.getRight() + params.rightMargin;
                final int right = left + mDivider.getIntrinsicWidth();
                mDivider.setBounds(left, top, right, bottom);
                mDivider.draw(c);
            }
        }
    }

    //判断是第一列
    private boolean isFirstColum(RecyclerView parent, int pos, int spanCount,
                                 int childCount)
    {
        LayoutManager layoutManager = parent.getLayoutManager();
        if (layoutManager instanceof GridLayoutManager)
        {
            if ((pos + 1) % spanCount == 1)
            {
                return true;
            }
        }
        return false;
    }

    //判断是最后一列
    private boolean isLastColum(RecyclerView parent, int pos, int spanCount,
                                int childCount)
    {
        LayoutManager layoutManager = parent.getLayoutManager();
        if (layoutManager instanceof GridLayoutManager)
        {
            if ((pos + 1) % spanCount == 0)
            {
                return true;
            }
        }
        return false;
    }

    //判断是最后一行
    private boolean isLastRaw(RecyclerView parent, int pos, int spanCount,
                              int childCount)
    {
        LayoutManager layoutManager = parent.getLayoutManager();
        if (layoutManager instanceof GridLayoutManager)
        {
//            childCount = childCount - childCount % spanCount;
//            if (pos >= childCount)
//                return true;
            int ranger = childCount % spanCount;
            if (ranger == 0)
            {
                ranger = spanCount;
            }
            childCount = childCount - ranger;
            if (pos >= childCount)
            {
                return true;
            }
        }
        return false;
    }

    //设置每个item的偏移量,从而展示分割线
    @Override
    public void getItemOffsets(Rect outRect, int itemPosition,
                               RecyclerView parent)
    {
        int spanCount = getSpanCount(parent);
        int childCount = parent.getAdapter().getItemCount();
        int marginRight = mDivider.getIntrinsicWidth();
        int marginBottom = mDivider.getIntrinsicHeight();
        if (isLastRaw(parent, itemPosition, spanCount, childCount))// 如果是最后一行,则不需要绘制底部
        {
            marginBottom = 0;
        }
        if (isLastColum(parent, itemPosition, spanCount, childCount))// 如果是最后一列,则不需要绘制右边
        {
            marginRight = 0;
        }
        outRect.set(0, 0, marginRight, marginBottom);
    }

    /**
     * 根据手机的分辨率从 dp 的单位 转成为 px(像素)
     */
    public int dip2px(float dpValue)
    {
        final float scale = mContext.getResources().getDisplayMetrics().density;
        return (int) (dpValue * scale + 0.5f);
    }

}

最后在RecyclerView中添加自定义分隔符即可:

recyclerView.addItemDecoration(new DividerItemDecoration(this));

注意:RecyclerView的高度需设为wrap_content

源码地址:github

参考文章: Android RecyclerView 使用完全解析 体验艺术般的控件

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值