RecycleView的ItemDecoration详解

RecycleView的ItemDecoration详解

ItemDecoration:顾名思义,就是给RecycleView的Item项做装饰的

1. 系统默认实现

DividerItemDecoration 是系统提供给我们的实现,可以实现 LinearLayoutManager 中的分割线效果,但是其他的 LayoutManager 就得我们自己写了

  //添加分割线
  recycle.addItemDecoration(DividerItemDecoration(this, DividerItemDecoration.VERTICAL))

默认样式如下:
在这里插入图片描述
DividerItemDecoration 我们可以通过修改系统参数的情况下自定义分割线效果

1、找到res/values/styles.xml,在其中声明android:listDivider属性,然后使用我们自己的样式

<resources>
    <!-- Base application theme. -->
    <style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
        <!-- Customize your theme here. -->
        <item name="colorPrimary">@color/colorPrimary</item>
        <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
        <item name="colorAccent">@color/colorAccent</item>
        <!--添加默认分割线的样式-->
        <item name="android:listDivider">@drawable/my_divider</item>
    </style>
</resources>

2、在res/drawable目录下声明我们自己的样式my_divider.xml

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="rectangle" >
    <gradient
        android:centerColor="#ff00ff"
        android:endColor="#00ff00"
        android:startColor="#0000ff"
        android:type="linear" />
    <size android:height="4dp"/>
</shape>

这样,使用自定义分割线后的样式如下:
在这里插入图片描述

2、 ItemDecoration 绘制顺序

ItemDecoration是一个抽象类,源码如下:

  public abstract static class ItemDecoration {
        /**
         * Draw any appropriate decorations into the Canvas supplied to the RecyclerView.
         * Any content drawn by this method will be drawn before the item views are drawn,
         * and will thus appear underneath the views.
         *
         * @param c Canvas to draw into
         * @param parent RecyclerView this ItemDecoration is drawing into
         * @param state The current state of RecyclerView
         */
        public void onDraw(@NonNull Canvas c, @NonNull RecyclerView parent, @NonNull State state) {
            onDraw(c, parent);
        }

        /**
         * @deprecated
         * Override {@link #onDraw(Canvas, RecyclerView, RecyclerView.State)}
         */
        @Deprecated
        public void onDraw(@NonNull Canvas c, @NonNull RecyclerView parent) {
        }

        /**
         * Draw any appropriate decorations into the Canvas supplied to the RecyclerView.
         * Any content drawn by this method will be drawn after the item views are drawn
         * and will thus appear over the views.
         *
         * @param c Canvas to draw into
         * @param parent RecyclerView this ItemDecoration is drawing into
         * @param state The current state of RecyclerView.
         */
        public void onDrawOver(@NonNull Canvas c, @NonNull RecyclerView parent,
                @NonNull State state) {
            onDrawOver(c, parent);
        }

        /**
         * @deprecated
         * Override {@link #onDrawOver(Canvas, RecyclerView, RecyclerView.State)}
         */
        @Deprecated
        public void onDrawOver(@NonNull Canvas c, @NonNull RecyclerView parent) {
        }


        /**
         * @deprecated
         * Use {@link #getItemOffsets(Rect, View, RecyclerView, State)}
         */
        @Deprecated
        public void getItemOffsets(@NonNull Rect outRect, int itemPosition,
                @NonNull RecyclerView parent) {
            outRect.set(0, 0, 0, 0);
        }

        /**
         * Retrieve any offsets for the given item. Each field of <code>outRect</code> specifies
         * the number of pixels that the item view should be inset by, similar to padding or margin.
         * The default implementation sets the bounds of outRect to 0 and returns.
         *
         * <p>
         * If this ItemDecoration does not affect the positioning of item views, it should set
         * all four fields of <code>outRect</code> (left, top, right, bottom) to zero
         * before returning.
         *
         * <p>
         * If you need to access Adapter for additional data, you can call
         * {@link RecyclerView#getChildAdapterPosition(View)} to get the adapter position of the
         * View.
         *
         * @param outRect Rect to receive the output.
         * @param view    The child view to decorate
         * @param parent  RecyclerView this ItemDecoration is decorating
         * @param state   The current state of RecyclerView.
         */
        public void getItemOffsets(@NonNull Rect outRect, @NonNull View view,
                @NonNull RecyclerView parent, @NonNull State state) {
            getItemOffsets(outRect, ((LayoutParams) view.getLayoutParams()).getViewLayoutPosition(),
                    parent);
        }
    }

抽取出核心方法翻译过来

public static abstract class ItemDecoration {
       
        // 在itemView绘制完成之前调用,也就是说此方法draw出来的效果将会在itemView的下面
        public void onDraw(Canvas c, RecyclerView parent, State state) {
            onDraw(c, parent);
        }

        //与onDraw相反,draw出来的效果将叠加在itemView的上面
        public void onDrawOver(Canvas c, RecyclerView parent, State state) {
            onDrawOver(c, parent);
        }

         //算通过配置outRect来设置itemView的inset边界,相当于设置itemView的margin
        @Deprecated
        public void getItemOffsets(Rect outRect, int itemPosition, RecyclerView parent) {
            outRect.set(0, 0, 0, 0);
        }
    }

如图所示:
在这里插入图片描述
outRect 设置就是 item 4周的 magin ,然后配合 onDraw ,onDrawOver 方法操作
onDraw 相当于画背景,在 item 之前绘制,onDrawOver 相当于画前景,在 item 之后绘制
在这里插入图片描述

3. ItemDecoration 是可以添加多个的

recyclerView.addItemDecoration(new SimpleDividerDecoration(this));
recyclerView.addItemDecoration(new LeftAndRightTagDecoration(this));
比如上面这个,SimpleDividerDecoration 画上下分割线,设置 item 4周 magin ,
LeftAndRightTagDecoration 画标签

More

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值