RecyclerView的分割线Decoration,五种实现方式,线性布局展示

 

上面三张图片中的item分割线就是效果图

一、首先定义LinearLayout布局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="match_parent">

    <android.support.v7.widget.RecyclerView
        android:id="@+id/homePageTab02RecyclerView"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_margin="5dp">

    </android.support.v7.widget.RecyclerView>

</LinearLayout>

 

二、在activity或fragment中查找View,并设置RecyclerView显示布局,一共三种布局:线性布局,网格布局,流式布局(瀑布布局)

这里使用线性布局方式:recyclerView = view.findViewById(R.id.homePageTab02RecyclerView);
LinearLayoutManager linearLayoutManager = new LinearLayoutManager(getContext());
//通过下面这行设置RecyclerView的布局显示方式
recyclerView.setLayoutManager(linearLayoutManager);

三、五种实现分割线的方式

1. 分割线官方提供的方式:最简单实现
 recyclerView.addItemDecoration(new DividerItemDecoration(getContext(), LinearLayout.VERTICAL));实现效果如下:

2.  使用官方提供的方式,在Drawable自定义一个shape,里面定义分割线的颜色

  2.1 首先在drawable中创建一个shape:

    

  2.2 代码中调用如下,就可以实现下图中这种彩色的分割线:

DividerItemDecoration decoration = new DividerItemDecoration(getContext(),LinearLayout.VERTICAL);
decoration.setDrawable(ContextCompat.getDrawable(getContext(), R.drawable.recycler_item_color));
recyclerView.addItemDecoration(decoration);

 3. 自定义类继承RecyclerView.ItemDecoration,重写一些方法来实现

   3.1 下面重写RecyclerView的ItemDecoration类,建议直接复制如下代码

public class MyRecyclerViewDecoration extends RecyclerView.ItemDecoration {
    private Context mContext;
    private Drawable mDivider;
    private int mOrientation;
    public static final int HORIZONTAL = LinearLayoutManager.HORIZONTAL;
    public static final int VERTICAL = LinearLayoutManager.VERTICAL;

    //我们通过获取系统属性中的listDivider来添加,在系统中的AppTheme中设置
    public static final int[] ATRRS = new int[]{
            android.R.attr.listDivider
    };

    public MyRecyclerViewDecoration(Context context, int orientation) {
        this.mContext = context;
        final TypedArray ta = context.obtainStyledAttributes(ATRRS);
        this.mDivider = ta.getDrawable(0);
        ta.recycle();
        setOrientation(orientation);
    }

    //设置屏幕的方向
    public void setOrientation(int orientation) {
        if (orientation != HORIZONTAL && orientation != VERTICAL) {
            throw new IllegalArgumentException("invalid orientation");
        }
        mOrientation = orientation;
    }

    @Override
    public void onDraw(Canvas c, RecyclerView parent, RecyclerView.State state) {
        if (mOrientation == HORIZONTAL) {
            drawVerticalLine(c, parent, state);
        } else {
            drawHorizontalLine(c, parent, state);
        }
    }

    //画横线, 这里的parent其实是显示在屏幕显示的这部分
    public void drawHorizontalLine(Canvas c, RecyclerView parent, RecyclerView.State state) {
        int left = parent.getPaddingLeft();
        int right = parent.getWidth() - parent.getPaddingRight();
        final int childCount = parent.getChildCount();
        for (int i = 0; i < childCount; i++) {
            final View child = parent.getChildAt(i);

            //获得child的布局信息
            final RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child
                    .getLayoutParams();
            final int top = child.getBottom() + params.bottomMargin;
            final int bottom = top + mDivider.getIntrinsicHeight();
            mDivider.setBounds(left + params.leftMargin, top, right - params.leftMargin, bottom);
            mDivider.draw(c);
            //Log.d("wnw", left + " " + top + " "+right+"   "+bottom+" "+i);
        }
    }

    //画竖线
    public void drawVerticalLine(Canvas c, RecyclerView parent, RecyclerView.State state) {
        int top = parent.getPaddingTop();
        int bottom = parent.getHeight() - parent.getPaddingBottom();
        final int childCount = parent.getChildCount();
        for (int i = 0; i < childCount; i++) {
            final View child = parent.getChildAt(i);

            //获得child的布局信息
            final RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child
                    .getLayoutParams();
            final int left = child.getRight() + params.rightMargin;
            final int right = left + mDivider.getIntrinsicWidth();
            mDivider.setBounds(left, top, right, bottom);
            mDivider.draw(c);
        }
    }

    //由于Divider也有长宽高,每一个Item需要向下或者向右偏移
    @Override
    public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State
            state) {
        if (mOrientation == HORIZONTAL) {
            //画横线,就是往下偏移一个分割线的高度
            outRect.set(0, 0, 0, mDivider.getIntrinsicHeight());
        } else {
            //画竖线,就是往右偏移一个分割线的宽度
            outRect.set(0, 0, mDivider.getIntrinsicWidth(), 0);
        }
    }
}

3.2 然后在drawable中创建shape,自定义分割线的颜色或样式

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
    <solid android:color="#22ff00" />
    <size
        android:width="2dp"
        android:height="2dp" />
</shape>

3.3 然后在Style中引用自己的drawable中的自定义颜色选择器

<item name="android:listDivider">@drawable/recycler_item_color</item>

3.4 调用方式,使用方法:

recyclerView.addItemDecoration(new MyRecyclerViewDecoration(getContext(),MyRecyclerViewDecoration.VERTICAL));或

recyclerView.addItemDecoration(new MyRecyclerViewDecoration(getContext(),LinearLayout.VERTICAL));

3.5 效果图:

4. 最笨办法,也相对很简单的方式实现,在每个item.xml文件中在最下面指定一条分割线

5. 万能分割线,直接复制即可

public class RecycleViewDivider extends RecyclerView.ItemDecoration {

    private Paint mPaint;
    private Drawable mDivider;
    private int mDividerHeight = 2;//分割线高度,默认为1px
    private int mOrientation;//列表的方向:LinearLayoutManager.VERTICAL或LinearLayoutManager.HORIZONTAL
    private static final int[] ATTRS = new int[]{android.R.attr.listDivider};

    /**
     * 默认分割线:高度为2px,颜色为灰色
     *
     * @param context
     * @param orientation 列表方向
     */
    public RecycleViewDivider(Context context, int orientation) {
        if (orientation != LinearLayoutManager.VERTICAL && orientation != LinearLayoutManager.HORIZONTAL) {
            throw new IllegalArgumentException("请输入正确的参数!");
        }
        mOrientation = orientation;

        final TypedArray a = context.obtainStyledAttributes(ATTRS);
        mDivider = a.getDrawable(0);
        a.recycle();
    }

    /**
     * 自定义分割线
     *
     * @param context
     * @param orientation 列表方向
     * @param drawableId  分割线图片
     */
    public RecycleViewDivider(Context context, int orientation, int drawableId) {
        //this(context, orientation);
        mDivider = ContextCompat.getDrawable(context, drawableId);
        mDividerHeight = mDivider.getIntrinsicHeight();
    }

    /**
     * 自定义分割线
     *
     * @param context
     * @param orientation   列表方向
     * @param dividerHeight 分割线高度
     * @param dividerColor  分割线颜色
     */
    public RecycleViewDivider(Context context, int orientation, int dividerHeight, int dividerColor) {
        //this(context, orientation);
        mDividerHeight = dividerHeight;
        mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        mPaint.setColor(dividerColor);
        mPaint.setStyle(Paint.Style.FILL);
    }


    //获取分割线尺寸
    @Override
    public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {
        super.getItemOffsets(outRect, view, parent, state);
//        outRect.set(0, 0, 0, mDividerHeight);
        if (mOrientation == LinearLayoutManager.VERTICAL) {
            outRect.set(0, 0, 0, mDividerHeight);
        } else {
            outRect.set(0, 0, mDividerHeight, 0);
        }
    }

    //绘制分割线
    @Override
    public void onDraw(Canvas c, RecyclerView parent, RecyclerView.State state) {
        super.onDraw(c, parent, state);
        if (mOrientation == LinearLayoutManager.VERTICAL) {
            drawVertical(c, parent);
        } else {
            drawHorizontal(c, parent);
        }
    }

    //绘制横向 item 分割线
    private void drawHorizontal(Canvas canvas, RecyclerView parent) {
        final int left = parent.getPaddingLeft();
        final int right = parent.getMeasuredWidth() - parent.getPaddingRight();
        final int childSize = parent.getChildCount();
        for (int i = 0; i < childSize; i++) {
            final View child = parent.getChildAt(i);
            RecyclerView.LayoutParams layoutParams = (RecyclerView.LayoutParams) child.getLayoutParams();
            final int top = child.getBottom() + layoutParams.bottomMargin;
            final int bottom = top + mDividerHeight;
            if (mDivider != null) {
                mDivider.setBounds(left, top, right, bottom);
                mDivider.draw(canvas);
            }
            if (mPaint != null) {
                canvas.drawRect(left, top, right, bottom, mPaint);
            }
        }
    }

    //绘制纵向 item 分割线
    private void drawVertical(Canvas canvas, RecyclerView parent) {
        final int top = parent.getPaddingTop();
        final int bottom = parent.getMeasuredHeight() - parent.getPaddingBottom();
        final int childSize = parent.getChildCount();
        for (int i = 0; i < childSize; i++) {
            final View child = parent.getChildAt(i);
            RecyclerView.LayoutParams layoutParams = (RecyclerView.LayoutParams) child.getLayoutParams();
            final int left = child.getRight() + layoutParams.rightMargin;
            final int right = left + mDividerHeight;
            if (mDivider != null) {
                mDivider.setBounds(left, top, right, bottom);
                mDivider.draw(canvas);
            }
            if (mPaint != null) {
                canvas.drawRect(left, top, right, bottom, mPaint);
            }
        }
    }
}

使用方法:
recyclerView.addItemDecoration(new RecycleViewDivider(
getActivity(), LinearLayoutManager.VERTICAL, 1, getResources().getColor(R.color.xxx)));

第五种万能分隔符效果图: 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
RecyclerView分割线可以通过设置ItemDecoration实现。下面是一个示例代码: 首先,创建一个分割线的类,继承自RecyclerView.ItemDecoration: ```java public class DividerItemDecoration extends RecyclerView.ItemDecoration { private Drawable mDivider; public DividerItemDecoration(Context context) { // 获取系统默认的分割线Drawable TypedArray styledAttributes = context.obtainStyledAttributes(new int[]{android.R.attr.listDivider}); mDivider = styledAttributes.getDrawable(0); styledAttributes.recycle(); } @Override public void onDraw(Canvas c, RecyclerView parent, RecyclerView.State state) { int left = parent.getPaddingLeft(); int right = parent.getWidth() - parent.getPaddingRight(); int childCount = parent.getChildCount(); for (int i = 0; i < childCount; i++) { View child = parent.getChildAt(i); RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child.getLayoutParams(); int top = child.getBottom() + params.bottomMargin; int bottom = top + mDivider.getIntrinsicHeight(); mDivider.setBounds(left, top, right, bottom); mDivider.draw(c); } } } ``` 然后,在使用RecyclerView的地方,添加分割线: ```java RecyclerView recyclerView = findViewById(R.id.recyclerView); recyclerView.addItemDecoration(new DividerItemDecoration(this)); ``` 这样就可以在RecyclerView的每个Item之间添加一个默认的分割线了。如果需要自定义分割线的样式,可以修改DividerItemDecoration类中的绘制逻辑或者使用其他Drawable替代mDivider。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值