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

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

文章目录

一、RecyclerView.ItemDecoration 简介

1、onDraw() 方法

2、onDrawOver () 方法

3、getItemOffsets () 方法

二、RecyclerView.ItemDecoration 源码注释解析

三、RecyclerView 相关资料





一、RecyclerView.ItemDecoration 简介


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


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



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


// 绘制底层背景
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 的当前状态 ;



函数原型如下 :


     

/**
         * 在提供给 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 的当前状态 ;



函数原型如下 :


   

/**
         * 在提供给 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 的当前状态 ;



函数原型如下 :


     

/**
         * 检索任何设置给 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 源码 : 只添加了中文注释 ;


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 打开 )


目录
相关文章
|
XML Android开发 数据格式
进入Activity时,为何页面布局内View#onMeasure会被调用两次?
进入Activity时,为何页面布局内View#onMeasure会被调用两次?
|
Android开发 开发者
RecyclerView定制:通用ItemDecoration及全展开RecyclerView的实现
RecyclerView定制:通用ItemDecoration及全展开RecyclerView的实现
456 0
RecyclerView定制:通用ItemDecoration及全展开RecyclerView的实现
|
Android开发
【RecyclerView】 九、为 RecyclerView 设置不同的布局样式
【RecyclerView】 九、为 RecyclerView 设置不同的布局样式
283 0
【RecyclerView】 九、为 RecyclerView 设置不同的布局样式
|
存储 缓存 开发工具
RecyclerView#Adapter#notifyDataSetChanged方法后,为何还会新建ViewHolder?
RecyclerView#Adapter#notifyDataSetChanged方法后,为何还会新建ViewHolder?
|
前端开发 Android开发
RecyclerView实现吸底效果—ItemDecoration
RecyclerView实现吸底效果—ItemDecoration
RecyclerView学习-RecyclerView#Adapter#notifyDataSetChanged是如何更新数据的?
RecyclerView学习-RecyclerView#Adapter#notifyDataSetChanged是如何更新数据的?
RecyclerView#smoothScrollToPosition调用RecyclerView#OnScrollListener的过程
项目中使用到了RecyclerView#smoothScrollToPosition(0)方法让Recyclerview滚动到顶部,同时给Recyclerview设置了监听器RecyclerView.OnScrollListener。
|
Android开发
同一页面实现recycleView三种布局【recycleView + adapter】
同一页面实现recycleView三种布局【recycleView + adapter】
158 0
RecycleView的操作(自定义SnapHelper、ItemDecoration)
RecycleView的操作(自定义SnapHelper、ItemDecoration)
327 0
|
缓存 Android开发
Android RecyclerView 绘制流程及Recycler缓存(上)
RecyclerView 源码一万多行,想全部读懂学会挺麻烦的,感兴趣的可以自己去瞅瞅,这篇文章重点来看下 RecyclerView是如何一步步将每一个 ItemView 显示到屏幕上,然后再分析在显示和滑动过程中,是如何通过缓存复用来提升整体性能的。 RecyclerView本质上也是一个 自定义控件 ,因此我们可以沿着分析其 onMeasure -> onLayout -> onDraw 这 3 个方法的路线来深入研究。
247 0
Android RecyclerView 绘制流程及Recycler缓存(上)