【RecyclerView】 八、RecyclerView.ItemDecoration 条目装饰 ( onDraw 和 onDrawOver 绘制要点 )(一)

简介: 【RecyclerView】 八、RecyclerView.ItemDecoration 条目装饰 ( onDraw 和 onDrawOver 绘制要点 )(一)

文章目录

一、onDraw 和 onDrawOver 绘制要点

二、onDraw 方法示例

三、onDrawOver 方法示例

四、完整代码示例

五、RecyclerView 相关资料





一、onDraw 和 onDrawOver 绘制要点


onDraw 和 onDrawOver 方法原理类似 , 都是基于 Canvas 进行绘制 , 这个 Canvas 的画布大小与 RecyclerView 大小相同 , 这里要注意 , 每一次绘制时 , 都要先获取要绘制的 item 组件对应的坐标 ;


这里的用法与 getItemOffsets 完全不同 , 设置每个元素的边距偏移时 , 可以获取当前的序号 , 并针对不同的序号代表的 item 条目进行不同的边距设置 ;


Canvas 中绘图的坐标系的 ( 0, 0 ) 位置是 RecyclerView 的左上角位置 ;


使用 Canvas 绘图时 , 先获取指定组件 , 然后获取该组件相对于父容器 ( RecyclerView ) 的坐标 ;



绘图的流程 :


① 获取组件个数 ;


② 遍历组件 ;


③ 获取组件 View 对象 ;


④ 获取组件 View 对象相对于父容器 RecyclerView 的坐标值 , 也就是左上右下四个坐标 ;


⑤ 根据获取的坐标值进行绘图 ;



绘图代码示例 : 以 onDraw 方法为例 , onDrawOver 的绘图逻辑类似 ;


       

@Override
            public void onDraw(@NonNull Canvas c, @NonNull RecyclerView parent, 
                   @NonNull RecyclerView.State state) {
        // 1. 获取当前的组件个数
                int itemCount = parent.getChildCount();     
    // 2. 遍历当前的所有组件 
                for (int i = 0; i < itemCount; i++) {       
                  // 3. 获取组件 View 对象 
                    View view = parent.getChildAt(i);
      // 4. 获取 item 组件相对于父容器的坐标 
      int left = view.getLeft();
                    int top = view.getTop();  
                    int right = view.getRight();          
                    int bottom = view.getBottom();    
      // 5. 根据上述坐标进行绘图 
      c.draw...
                }
            }






二、onDraw 方法示例


这里给出一个需求 , 为每一行的第一个元素 , 添加红色矩形背景 , 范围是每隔 item 向外延展 5 55 像素 ;


代码示例 :


 

@Override
    public void onDraw(@NonNull Canvas c, @NonNull RecyclerView parent,
                       @NonNull RecyclerView.State state) {
        // 1. 获取当前的组件个数
        int itemCount = parent.getChildCount();
        // 2. 遍历当前的所有组件
        for (int i = 0; i < itemCount; i++) {
            // 3. 获取组件 View 对象
            View view = parent.getChildAt(i);
            // 4. 获取 item 组件相对于父容器的坐标
            int left = view.getLeft();
            int top = view.getTop();
            int right = view.getRight();
            int bottom = view.getBottom();
            // 5. 根据上述坐标进行绘图
            if (i % 4 == 0){
                // 给每一行的第一个元素绘制红色矩形背景, 向外延展 5 像素
                Paint paint = new Paint();
                paint.setColor(Color.RED);
                c.drawRect(left - 5, top - 5, right + 5, bottom + 5, paint);
            }
        }
    }


运行效果 : 绘制的矩形被 item 组件元素覆盖了 , 因此只显示出外层的一圈边框 ;


image.png






三、onDrawOver 方法示例


给每个 item 条目设置上绘制一个遮罩 , 偶数序号的元素绘制蓝色圆形遮罩 , 奇数序号的元素上绘制红色矩形遮罩 ;


 

@Override
    public void onDrawOver(@NonNull Canvas c, @NonNull RecyclerView parent,
                           @NonNull RecyclerView.State state) {
        // 1. 获取当前的组件个数
        int itemCount = parent.getChildCount();
        // 2. 遍历当前的所有组件
        for (int i = 0; i < itemCount; i++) {
            // 3. 获取组件 View 对象
            View view = parent.getChildAt(i);
            // 4. 获取 item 组件相对于父容器的坐标
            int left = view.getLeft();
            int top = view.getTop();
            int right = view.getRight();
            int bottom = view.getBottom();
            // 5. 根据上述坐标进行绘图
            if (i % 2 == 0){
                // 偶数序号的元素绘制蓝色圆形遮罩
                Paint paint = new Paint();
                paint.setColor(Color.BLUE);
                paint.setStyle(Paint.Style.STROKE);
                paint.setStrokeWidth(5F);
                c.drawCircle((left + right) / 2F, (top + bottom) / 2F, (right - left) / 4F, paint);
            }else{
                // 奇数序号的元素绘制红色矩形遮罩
                Paint paint = new Paint();
                paint.setColor(Color.RED);
                paint.setStyle(Paint.Style.STROKE);
                paint.setStrokeWidth(5F);
                c.drawRect(left + 20, top + 20, right - 20, bottom - 20, paint);
            }
        }
    }



运行效果 : 偶数序号的元素绘制蓝色圆形遮罩 , 奇数序号的元素上绘制红色矩形遮罩 ; 该方法中绘制的元素覆盖 item 组件元素 ;

image.png


目录
相关文章
|
6月前
|
XML 数据格式
RecyclerView使用示例(瀑布流)
RecyclerView使用示例(瀑布流)
55 0
|
XML Android开发 数据格式
进入Activity时,为何页面布局内View#onMeasure会被调用两次?
进入Activity时,为何页面布局内View#onMeasure会被调用两次?
|
Android开发 开发者
RecyclerView定制:通用ItemDecoration及全展开RecyclerView的实现
RecyclerView定制:通用ItemDecoration及全展开RecyclerView的实现
448 0
RecyclerView定制:通用ItemDecoration及全展开RecyclerView的实现
|
Android开发
【RecyclerView】 九、为 RecyclerView 设置不同的布局样式
【RecyclerView】 九、为 RecyclerView 设置不同的布局样式
276 0
【RecyclerView】 九、为 RecyclerView 设置不同的布局样式
利用RecyclerView实现无限轮播广告条2
利用RecyclerView实现无限轮播广告条
利用RecyclerView实现无限轮播广告条1
利用RecyclerView实现无限轮播广告条
RecyclerView#smoothScrollToPosition调用RecyclerView#OnScrollListener的过程
项目中使用到了RecyclerView#smoothScrollToPosition(0)方法让Recyclerview滚动到顶部,同时给Recyclerview设置了监听器RecyclerView.OnScrollListener。
|
Android开发
同一页面实现recycleView三种布局【recycleView + adapter】
同一页面实现recycleView三种布局【recycleView + adapter】
151 0
同一页面实现recycleView三种布局【recycleView + adapter】
RecycleView的操作(自定义SnapHelper、ItemDecoration)
RecycleView的操作(自定义SnapHelper、ItemDecoration)
314 0
|
Android开发
【RecyclerView】 八、RecyclerView.ItemDecoration 条目装饰 ( onDraw 和 onDrawOver 绘制要点 )(二)
【RecyclerView】 八、RecyclerView.ItemDecoration 条目装饰 ( onDraw 和 onDrawOver 绘制要点 )(二)
157 0
【RecyclerView】 八、RecyclerView.ItemDecoration 条目装饰 ( onDraw 和 onDrawOver 绘制要点 )(二)