首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

RecyclerView -在项目装饰的onDraw方法中获取适配器位置?

在Android开发中,RecyclerView 是一个非常常用的组件,用于显示大量数据列表,并且能够高效地回收和重用视图。当你在 RecyclerView 的装饰器(Decorator)的 onDraw 方法中需要获取适配器的位置时,可以通过以下步骤实现:

基础概念

  • RecyclerView: 是一个更高级和灵活的 ListView,它提供了局部刷新的能力,支持多种布局管理器,并且能够高效地重用视图。
  • 装饰器(Decorator): 是 RecyclerView 提供的一种机制,允许你在不修改 RecyclerView 或其子视图的情况下,添加额外的绘制逻辑或布局逻辑。

获取适配器位置的方法

onDraw 方法中,你可以通过 RecyclerViewgetChildAdapterPosition(View) 方法来获取某个视图在适配器中的位置。

示例代码

以下是一个简单的装饰器示例,它在 onDraw 方法中打印出每个视图的适配器位置:

代码语言:txt
复制
public class MyItemDecoration extends RecyclerView.ItemDecoration {
    @Override
    public void onDraw(Canvas c, RecyclerView parent, RecyclerView.State state) {
        super.onDraw(c, parent, state);

        for (int i = 0; i < parent.getChildCount(); i++) {
            View child = parent.getChildAt(i);
            int position = parent.getChildAdapterPosition(child);
            Log.d("MyItemDecoration", "View at position: " + position);
            // 在这里你可以添加你的绘制逻辑
        }
    }
}

应用场景

  • 自定义分割线: 你可以使用装饰器来绘制自定义的分割线,并且根据每个视图的位置来调整分割线的样式。
  • 边距控制: 如果你需要为列表项添加不同的边距,可以使用装饰器来实现。
  • 动态背景: 根据列表项的位置来动态改变背景颜色或其他视觉效果。

注意事项

  • 性能考虑: 在 onDraw 方法中进行复杂的计算或频繁的调用可能会影响性能,因此应该尽量保持这里的逻辑简单高效。
  • 视图重用: 由于 RecyclerView 的视图重用机制,当视图被回收并重新使用时,其位置可能会发生变化,因此在 onDraw 中获取的位置是当前有效的。

可能遇到的问题及解决方法

问题: 在 onDraw 方法中获取到的位置不正确。 原因: 可能是因为视图被回收并重新使用了,导致位置信息不再准确。 解决方法: 确保在 onDraw 方法中获取位置时,视图仍然是有效的,并且没有被回收。如果需要根据位置做复杂的逻辑处理,可以考虑在适配器的 onBindViewHolder 方法中进行计算,并将结果存储在视图的标签(Tag)中,然后在装饰器中读取这些标签。

通过以上方法,你可以在 RecyclerView 的装饰器中正确地获取到每个视图的适配器位置,并据此实现各种自定义的绘制效果。

页面内容是否对你有帮助?
有帮助
没帮助

相关·内容

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

) 1、onDraw() 方法 onDraw方法 : 在提供给 RecyclerView 的画布上绘制合适的装饰 , 在该方法中绘制的任何内容, 都在 item 布局组件绘制之前绘制, 绘制的内容都被...: 在提供给 RecyclerView 的画布上绘制合适的装饰, 在该方法中绘制的任何内容, 都在 item 布局组件绘制之后绘制, 绘制的内容会覆盖 item 布局, 显示在 item 布局上层 ;...Adapter 适配器中的关联数据 , 调用 RecyclerView.getChildAdapterPosition(View) , 方法获取适配器中的该 View 组件位置 ; 然后将特殊位置可以设置不同的参数...(View) * 方法获取适配器中的该 View 组件位置 ; * * @param outRect 接受输出的矩形...(View) * 方法获取适配器中的该 View 组件位置 ; * * @param outRect 接受输出的矩形

60800

RecyclerView中获取点击位置的接口被废弃了?

仔细一看,holder.adapterPosition这不就是我们平时在RecyclerView里面用于获取点击位置的方法么,常用写法如下: holder.itemView.setOnClickListener...不过MergeAdapter是在RecyclerView 1.2.0版本中才新增的,而官网目前RecyclerView的最新稳定版本还是1.1.0。...从名字上就可以看出来了,一个是用于获取元素位于当前绑定Adapter的位置,一个是用于获取元素位于Adapter中的绝对位置。 如果觉得我上面的解释还不够清楚,通过下面的示例看一下你立马就能明白了。...很明显,我们获取到的点击位置是元素位于BodyAdapter中的位置。...结果一目了解,获取到的点击位置是元素位于合并后Adapter中的位置。

4.5K43
  • 【RecyclerView】 七、RecyclerView.ItemDecoration 条目装饰 ( getItemOffsets 边距设置 )

    方法说明 ---- RecyclerView.ItemDecoration 是抽象类 , 当前使用的 onDraw , onDrawOver , getItemOffsets 3 个方法 , 上一篇博客...【RecyclerView】 五、RecyclerView.ItemDecoration 条目装饰 ( 简介 | onDraw | onDrawOver | getItemOffsets ) 二、RecyclerView.ItemDecoration...源码注释解析 中已经分析了 RecyclerView.ItemDecoration 方法 , 并查看了其源码 , 这 3 个方法都是空方法 , 因此这里实现方法时 , 不必再使用 super 调用父类方法...; 调用 RecyclerView 对象的 getChildAdapterPosition 方法 , 传入 item 组件 View 参数 , 就可以获取当前的位置 ; @Override...获取当前设置边距的位置 int currentPosition = parent.getChildAdapterPosition(view); } 获取到当前设置位置之后 , 根据不同的位置设置不同的偏移量

    5.6K00

    教你玩转 Android RecyclerView:深入解析 RecyclerView.ItemDecoration类(含实例讲解)

    ` 添加装饰 即绘制更多内容,丰富ItemView的UI效果 ---- 2....state) { ... } // 方法3:onDrawOver() // 作用:同样是绘制内容,但与onDraw()的区别是:绘制在图层的最上层 @Override...的onDraw()绘制会先于ItemView的onDraw()绘制,所以如果在Itemdecoration的onDraw()中绘制的内容在ItemView边界内,就会被ItemView遮挡住。...的所有ItemView分别获取它们的位置信息,然后再绘制内容 此处遍历的RecyclerView的ItemView(即Child view),并不是 Adapter 设置的每一个 item,而是可见的...获取RecyclerView的Child view的个数 int childCount = parent.getChildCount(); // 遍历每个Item,分别获取它们的位置信息

    2K21

    getBoundingClientRect方法获取元素在页面中的相对位置

    获取元素位置可以用 offset 或 getBoundingClientRect,使用 offset 因为兼容性不好,比较麻烦,offset获取位置会形成“回溯”。...1.使用语法: element.getBoundingClientRect(); 方法中没有任何参数,返回值为对象类型。...2.在IE8及以下的浏览器中,返回值对象包含的属性值有: top::元素上边缘距离文档顶部的距离; right: 元素右边缘距离文档左边的距离; bottom:元素下边缘距离文档顶部的距离; left:...元素左边缘距离文档左边的距离; 3.在IE9以上、谷歌、火狐等浏览器中,返回值对象包含的属性值有: top: 元素上边缘距离文档顶部的距离; right:元素右边缘距离文档左边的距离; bottom:元素下边缘距离文档顶部的距离...width 和 height 属性的解决方法: 在IE8及以下浏览器中,可以通过计算得到元素的宽和高: 如: var dom = document.querySelector("#demo"), r

    3.9K20

    JS实现获取鼠标在画布中的位置

    JS实现获取鼠标在画布中的位置 效果展示 概述 本文讲解如何实现我们平时用的画布软件中,怎么获取的我们鼠标时刻在画布中的位置。...// 首先得到鼠标在页面中的坐标( e.pageX, e.pageY) // 其次得到盒子在页面中的距离(box.offsetLeft, box.offsetTop) /.../ 用鼠标距离页面的坐标减去盒子在页面中的距离, 得到 鼠标在盒子内的坐标 // 我们生活中常见的画布里面的那个获取鼠标的位置 就是这么实现的 var box = document.querySelector...// 首先得到鼠标在页面中的坐标( e.pageX, e.pageY) // 其次得到盒子在页面中的距离(box.offsetLeft, box.offsetTop) /.../ 用鼠标距离页面的坐标减去盒子在页面中的距离, 得到 鼠标在盒子内的坐标 // 我们生活中常见的画布里面的那个获取鼠标的位置 就是这么实现的 var box = document.querySelector

    6300

    RecyclerView必知必会

    但是RecyclerView的出现会让很多开源项目被废弃,例如横向滚动的ListView, 横向滚动的GridView, 瀑布流控件,因为RecyclerView能够实现所有这些功能。...我们来看下面的代码: 根据View的绘制流程,首先调用RecyclerView重写的draw()方法,随后super.draw()即调用View的draw(),该方法会先调用onDraw()(这个方法在...中获取合适的View,在后文的回收机制中会介绍该方法的具体实现。...那么如何在不破坏原有Adapter实现的情况下完成呢? 这里引入装饰器(Decorator)设计模式,该设计模式通过组合的方式,在不破话原有类代码的情况下,对原有类的功能进行扩展。...,该方法内部调用了makeAndAddView(),实现如下: 其中,getActiveView()是从mActiveViews中获取合适的View,如果获取到了,则直接返回,而不调用obtainView

    4.7K20

    RecycleView从0到0.1 | 技术创作特训营第一期

    onBindViewHolder: 通过方法提供的ViewHolder,将数据绑定到ViewHolder中。getItemCount: 获取数据源总的条数。...MyHolder : 这是RecyclerView.ViewHolder的实现类,用于初始化item布局中的子控件。需要注意的是,在这个类的构造方法中需要传递item布局的View给父类 。...StaggeredGridLayoutManager: 瀑布流布局,在分散对齐网格中显示项目。...我们可以在RecyclerView的Adapter中自定义一个接口,并创建一个供其他类设置监听的方法。...当我们定义好接口后,我们在onBindViewHolder()方法中为holder.itemView(itemView是列表中的每一个item项)设置了点击事件监听,然后在onClick()中判断是否有用户传递过

    44411

    RecyclerView 必知必会

    那么onDraw()是怎么被调用的呢?还有ItemDecoration还有一个方法onDrawOver(),该方法也可以被重写,那么onDraw()和onDrawOver()之间有什么关系呢?...根据View的绘制流程,首先调用RecyclerView重写的draw()方法,随后super.draw()即调用View的draw(),该方法会先调用onDraw()(这个方法在RecyclerView...其中next()调用了getViewForPosition(currentPosition),该方法是从RecyclerView的回收机制实现类Recycler中获取合适的View,在后文的回收机制中会介绍该方法的具体实现...在runPendingAnimations()中,animateAddImpl()是执行add动画的具体方法,其实就是将itemView的透明度从0变到1(在animateAdd()中已经将view的透明度变为...那么如何在不破坏原有Adapter实现的情况下完成呢? 这里引入装饰器(Decorator)设计模式,该设计模式通过组合的方式,在不破话原有类代码的情况下,对原有类的功能进行扩展。

    2.6K70

    RecyclerView 必知必会

    但是RecyclerView的出现会让很多开源项目被废弃,例如横向滚动的ListView, 横向滚动的GridView, 瀑布流控件,因为RecyclerView能够实现所有这些功能。...根据View的绘制流程,首先调用RecyclerView重写的draw()方法,随后super.draw()即调用View的draw(),该方法会先调用onDraw()(这个方法在RecyclerView...其中next()调用了getViewForPosition(currentPosition),该方法是从RecyclerView的回收机制实现类Recycler中获取合适的View,在后文的回收机制中会介绍该方法的具体实现...在runPendingAnimations()中,animateAddImpl()是执行add动画的具体方法,其实就是将itemView的透明度从0变到1(在animateAdd()中已经将view的透明度变为...那么如何在不破坏原有Adapter实现的情况下完成呢? 这里引入装饰器(Decorator)设计模式,该设计模式通过组合的方式,在不破话原有类代码的情况下,对原有类的功能进行扩展。

    4.2K90

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

    文章目录 一、onDraw 和 onDrawOver 绘制要点 二、onDraw 方法示例 三、onDrawOver 方法示例 四、完整代码示例 五、RecyclerView 相关资料 一、onDraw...和 onDrawOver 绘制要点 ---- onDraw 和 onDrawOver 方法原理类似 , 都是基于 Canvas 进行绘制 , 这个 Canvas 的画布大小与 RecyclerView..., 并针对不同的序号代表的 item 条目进行不同的边距设置 ; Canvas 中绘图的坐标系的 ( 0, 0 ) 位置是 RecyclerView 的左上角位置 ; 使用 Canvas 绘图时 ,...对象相对于父容器 RecyclerView 的坐标值 , 也就是左上右下四个坐标 ; ⑤ 根据获取的坐标值进行绘图 ; 绘图代码示例 : 以 onDraw 方法为例 , onDrawOver 的绘图逻辑类似..., 奇数序号的元素上绘制红色矩形遮罩 ; 该方法中绘制的元素覆盖 item 组件元素 ; 四、完整代码示例 ---- RecyclerView.ItemDecoration 代码示例 : package

    1.4K00

    【Android应用开发】RecycleView API 翻译 (文档翻译)

    Position(位置): 适配器(Adapter)中的数据项目位置. Index(索引): 一个已经附加的子组件的索引在getChildAt(int)方法中使用. 与Position形成对比....你可以依赖这些位置, 这些位置与用户当前在屏幕上看到的位置是一致的.例如, 如果你在屏幕上有一个项目列表, 用户要求使用第五个项目元素, 你可以使用这些方法, 因为这些方法对应的位置就是用户看到的位置....例如, 如果你触发了 ViewHolder 点击事件, 想要去获取适配器中的项目元素, 你应该使用 getAdapterPosition() 方法....注意这些方法可能不能去计算适配器的位置, 如果在 notifyDataSetChanged() 方法被调用, 同时新的布局在没有被计算时....该类定义了条目发生改变时 适配器 的动画效果. class RecyclerView.ItemDecoration 项目装饰, 在适配器数据集中指定的项目显示组件上, 添加一个特别的图画 和 布局.

    1.4K40

    Android 中为RecyclerView控件添加分隔线

    extends RecyclerView.ItemDecoration { // 在这个方法中绘制分隔线,这个方法会在RecyclerView中的子项绘制完成之前被调用 @Override...(c, parent, state); } // 也可以在这个方法中绘制分隔线,这个方法会在RecyclerView中的子项绘制完成之后被调用 @Override public...c, parent, state); } // 这个方法用于对子项的绘制位置进行一些必要的调整或者对子项进行一些其他的调整。..., state); } } 其实,onDraw 和 onDrawOver 方法我们只需要重写其中一个就行了,因为两个方法唯一的不同就是调用的先后问题。...:对RecyclerView的子项排布方式进行判断,两个方法分别用于绘制线性布局的分隔线和网格布局的分隔线,这两个方法主要是通过布局和控件的位置来计算出myDivider绘制的区域的一些位置信息,如果对于布局和控件的熟悉的话就没什么难点了

    2.1K10

    郭神的抽丝剥茧心法修炼: 深剖RecyclerView

    processAppeared,在该方法中,它调用了 RecyclerView#animateAppearance 方法,动画的任务最终也交给了 RecyclerView.ItemAnimator,RecyclerView.ItemAnimator...这里有必要说明一下,一些删除或者新增操作,通过使用适配器中通知删除或者新增的方法,最终还是会通知界面进行重绘。...1.5 onDraw RecylcerView 中的 onDraw 方法比较简单,仅仅绘制了 ItemDecoration,同样需要用户自定义实现: public void onDraw(Canvas...Adapter#onCreateViewHolder 方法,这也是我们继承适配器 Adapter 必须要实现的抽象方法,通常,我们在继承 Adapter 不会只创建 ViewHolder,还会做子 View...除了适配器模式之外,Adapter 中还使用观察者模式,这一点可以从 RecyclerView#setAdapter 方法中可以看出,设置适配器的时候,会对旧的 Adapter 取消注册监听器,接着对新的

    1.4K20

    Android RecyclerView之粘性头部+点击事件

    如下图所示: #######onDraw(Canvas c, RecyclerView parent, State state) 这个方法可以实现类似绘制背景的效果,绘制的东西是显示在item的下层,一般配合...的个数; onDraw(),onDrawOver()方法针对 RecyclerView本身,初始化只会调用一次; 当滑动列表至第10条的过程中,可以看到onDraw(),onDrawOver()...我们先看下这两个方法在 RecyclerView中调用位置,从下面也可以看得出来decoration 的onDraw(),child view 的 onDraw(),decoration 的 onDrawOver...这样就会调用RecyclerView的onDraw(),onDrawOver()方法,因此ItemDecoration的这两个方法就在不断的调用。...在获取绘制坐标的时候,主要在于确定纵坐标的起始位置距离顶部的大小。

    4.5K40

    【Android 事件分发】ItemTouchHelper 事件分发源码分析 ( 绑定 RecyclerView )

    条目中的装饰 , 可以在条目组件 底部 上层 绘制 Canvas 图形 // ItemTouchHelper 继承 RecyclerView.ItemDecoration...在 ItemTouchHelper.setupCallbacks 方法中 , 调用了 mRecyclerView.addItemDecoration(this); 方法 , 为当前的 RecyclerView...设置条目装饰 , 该装饰可以在条目组件 底部 上层 绘制 Canvas 图形 , 具体的方法如下 : public class RecyclerView extends ViewGroup implements...parent, @NonNull State state) 方法是绘制方法 , 在该方法中调用了 void onDraw(@NonNull Canvas c, @NonNull RecyclerView...} 参考 Android 官方提供的 RecyclerView.ItemDecoration 的实现类 DividerItemDecoration , 该类中重写了 onDraw 方法 , 其中调用了

    40020

    小甜点,RecyclerView 之 ItemDecoration 讲解及高级特性实践

    我们不妨在 AndroidStudio 中按 Ctrl 键点击方法名,就可以到了它被调用的位置。...onDraw() 在 Android 中的每一个 View 中 onDraw() 是很重要的一个方法,用来绘制组件的UI效果,所以在 ItemDecocration 中它自然也是用来绘制外观的。...需要注意的一点是 getItemOffsets 是针对每一个 ItemView,而 onDraw 方法却是针对 RecyclerView 本身,所以在 onDraw 方法中需要遍历屏幕上可见的 ItemView...,分别获取它们的位置信息,然后分别的绘制对应的分割线。...答案是肯定的,但不是在 onDraw() 方法实现,而是另外一个方法 onDrawOver()。 onDrawOver 和角标。 现实中的APP或者网站经常有一些排行榜比如下面: ?

    1.1K20
    领券