【RecyclerView】 六、RecyclerView.ItemDecoration 条目装饰 ( 简介 | onDraw | onDrawOver | getItemOffsets )

2023-03-28 21:05:41 浏览数 (1)

文章目录

  • 一、RecyclerView.ItemDecoration 简介
    • 1、onDraw() 方法
    • 2、onDrawOver () 方法
    • 3、getItemOffsets () 方法
  • 二、RecyclerView.ItemDecoration 源码注释解析
  • 三、RecyclerView 相关资料

一、RecyclerView.ItemDecoration 简介


RecyclerView.ItemDecoration 是 RecyclerView 的内部类 , ItemDecoration 顾名思义就是作为 Item 条目装饰用的 ;

可以控制 RecyclerView 条目组件的 边距 , 以及在 item 条目组件 底层绘制背景 , 在 item 条目组件 上层绘制装饰 ;

RecyclerView.ItemDecoration 使用时 , 可以选择重写以下三个方法 :

代码语言:javascript复制
// 绘制底层背景
public void onDraw(@NonNull Canvas c, @NonNull RecyclerView parent, @NonNull State state)
// 绘制上层装饰
public void onDrawOver(@NonNull Canvas c, @NonNull RecyclerView parent, @NonNull State state)
// 设置边距 
public void getItemOffsets(@NonNull Rect outRect, @NonNull View view,
                @NonNull RecyclerView parent, @NonNull State state)

1、onDraw() 方法

onDraw方法 : 在提供给 RecyclerView 的画布上绘制合适的装饰 , 在该方法中绘制的任何内容, 都在 item 布局组件绘制之前绘制, 绘制的内容都被 item 布局覆盖 ;

void onDraw(@NonNull Canvas c, @NonNull RecyclerView parent, @NonNull State state) 参数说明 :

① @NonNull Canvas c : 绘制背景的画布 ;

② @NonNull RecyclerView parent : 要添加装饰的 RecyclerView ;

③ @NonNull State state : RecyclerView 的当前状态 ;

函数原型如下 :

代码语言:javascript复制
        /**
         * 在提供给 RecyclerView 的画布上绘制合适的装饰.
         * 在该方法中绘制的任何内容, 都在 item 布局组件绘制之前绘制, 绘制的内容都被 item 布局覆盖.
         * 
         * @param c 绘制的画布
         * @param parent 要添加装饰的 RecyclerView
         * @param state RecyclerView 的当前状态 
         */
        public void onDraw(@NonNull Canvas c, @NonNull RecyclerView parent, @NonNull State state) {
            onDraw(c, parent);
        }

2、onDrawOver () 方法

onDrawOver : 在提供给 RecyclerView 的画布上绘制合适的装饰, 在该方法中绘制的任何内容, 都在 item 布局组件绘制之后绘制, 绘制的内容会覆盖 item 布局, 显示在 item 布局上层 ;

void onDrawOver(@NonNull Canvas c, @NonNull RecyclerView parent, @NonNull State state) 参数说明 :

① @NonNull Canvas c : 绘制背景的画布 ;

② @NonNull RecyclerView parent : 要添加装饰的 RecyclerView ;

③ @NonNull State state : RecyclerView 的当前状态 ;

函数原型如下 :

代码语言:javascript复制
        /**
         * 在提供给 RecyclerView 的画布上绘制合适的装饰.
         * 在该方法中绘制的任何内容, 都在 item 布局组件绘制之后绘制, 绘制的内容会覆盖 item 布局, 
         * 显示在 item 布局上层.
         *
         * @param c 绘制的画布
         * @param parent 要添加装饰的 RecyclerView
         * @param state RecyclerView 的当前状态 
         */
        public void onDrawOver(@NonNull Canvas c, @NonNull RecyclerView parent,
                @NonNull State state) {
            onDrawOver(c, parent);
        }

3、getItemOffsets () 方法

getItemOffsets 方法 : 设置当前的 item 条目布局组件的边距 , 效果类似于 padding 或 margin ; 默认值四个边距都是 0 ;

针对特殊位置的特殊设置 : 如果需要取访问 Adapter 适配器中的关联数据 , 调用 RecyclerView.getChildAdapterPosition(View) , 方法获取适配器中的该 View 组件位置 ; 然后将特殊位置可以设置不同的参数 , 即可实现 " 针对特殊位置的特殊设置 " 效果 ;

void getItemOffsets(@NonNull Rect outRect, @NonNull View view, @NonNull RecyclerView parent, @NonNull State state) 参数说明 :

① @NonNull Rect outRect : 接受输出的矩形 ;

② @NonNull View view : 要装饰的子 View ;

③ @NonNull RecyclerView parent : 该 ItemDecoration 正在装饰的 RecyclerView ;

④ @NonNull State state : RecyclerView 的当前状态 ;

函数原型如下 :

代码语言:javascript复制
        /**
         * 检索任何设置给 item 布局条目的偏移量.
         * outRect 的任何变量字段指定了 item 布局组件边距的像素值, 效果类似于 padding 或 margin.
         * outRect 默认的边距值都是 0.
         *
         * <p>
         * 如果想要针对某些位置的 item 条目组件设置的 ItemDecoration 不生效 , 
         * 应该设置 outRect 所有的 4 个字段值为 0 ;
         *
         * <p>
         * 如果需要取访问 Adapter 适配器中的关联数据 , 调用 RecyclerView.getChildAdapterPosition(View)
         * 方法获取适配器中的该 View 组件位置 ;
         *
         * @param outRect 接受输出的矩形 .
         * @param view    要装饰的子 View .
         * @param parent  该 ItemDecoration 正在装饰的 RecyclerView .
         * @param state   RecyclerView 的当前状态 .
         */
        public void getItemOffsets(@NonNull Rect outRect, @NonNull View view,
                @NonNull RecyclerView parent, @NonNull State state) {
            getItemOffsets(outRect, ((LayoutParams) view.getLayoutParams()).getViewLayoutPosition(),
                    parent);
        }

二、RecyclerView.ItemDecoration 源码注释解析


RecyclerView.ItemDecoration 源码 : 只添加了中文注释 ;

代码语言:javascript复制
public class RecyclerView extends ViewGroup implements ScrollingView,
        NestedScrollingChild2, NestedScrollingChild3 {
        
    /**
     * RecyclerView.ItemDecoration 允许应用在适配器中的 item 条目组件之外, 添加特殊的绘图和布局. 
     * 可以用于绘制 item 条目间的分割线, 高亮显示, 分组边界等等. 
     *
     * 所有的 ItemDecoration 会按照添加顺序绘制, 在 item 条目组件绘制前先执行 onDraw 方法 , 
     * 在 item 条目绘制之后执行 onDrawOver 方法.
     */
    public abstract static class ItemDecoration {
        /**
         * 在提供给 RecyclerView 的画布上绘制合适的装饰.
         * 在该方法中绘制的任何内容, 都在 item 布局组件绘制之前绘制, 绘制的内容都被 item 布局覆盖.
         * 
         * @param c 绘制的画布
         * @param parent 要添加装饰的 RecyclerView
         * @param state 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) {
        }

        /**
         * 在提供给 RecyclerView 的画布上绘制合适的装饰.
         * 在该方法中绘制的任何内容, 都在 item 布局组件绘制之后绘制, 绘制的内容会覆盖 item 布局, 
         * 显示在 item 布局上层.
         *
         * @param c 绘制的画布
         * @param parent 要添加装饰的 RecyclerView
         * @param state 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);
        }

        /**
         * 检索任何设置给 item 布局条目的偏移量.
         * outRect 的任何变量字段指定了 item 布局组件边距的像素值, 效果类似于 padding 或 margin.
         * outRect 默认的边距值都是 0.
         *
         * <p>
         * 如果想要针对某些位置的 item 条目组件设置的 ItemDecoration 不生效 , 
         * 应该设置 outRect 所有的 4 个字段值为 0 ;
         *
         * <p>
         * 如果需要取访问 Adapter 适配器中的关联数据 , 调用 RecyclerView.getChildAdapterPosition(View)
         * 方法获取适配器中的该 View 组件位置 ;
         *
         * @param outRect 接受输出的矩形 .
         * @param view    要装饰的子 View .
         * @param parent  该 ItemDecoration 正在装饰的 RecyclerView .
         * @param state   RecyclerView 的当前状态 .
         */
        public void getItemOffsets(@NonNull Rect outRect, @NonNull View view,
                @NonNull RecyclerView parent, @NonNull State state) {
            getItemOffsets(outRect, ((LayoutParams) view.getLayoutParams()).getViewLayoutPosition(),
                    parent);
        }
    }
}

三、RecyclerView 相关资料


官方文档 :

使用 RecyclerView 创建动态列表 : https://developer.android.google.cn/guide/topics/ui/layout/recyclerview

高级 RecyclerView 自定义 : https://developer.android.google.cn/guide/topics/ui/layout/recyclerview-custom

代码示例 :

GitHub 源码地址 : https://github.com/han1202012/001_RecyclerView

博客源码快照 : https://download.csdn.net/download/han1202012/14945904

( 使用 Android Studio 打开 )

0 人点赞