假设我有一个 RecyclerView
,其中 ViewHolder
绑定(bind)了一个布局,其中包含一个带有设置 ID 的 View
。
设计:
*RecyclerView
**ViewHolder0
***TextView with ID myTitle
**ViewHolder1
***TextView with ID myTitle
**ViewHolder2
***TextView with ID myTitle
**ViewHolder3
***TextView with ID myTitle
如果同时加载这些 View ,屏幕空间足以显示所有 ViewHolder
,如何获取 ID 为 myTitle 的所有 View ?
我尝试了基本的 findViewById(int ResourceID)
但是它只给了我第一个 TextView
并且只有当第一个从屏幕上消失并且可能从树我得到第二个。
注意:我自己不创建 View 树,但必须与其交互。
最佳答案
我做了一个示例应用程序来比较 findViewHolderForAdapterPosition
, findViewHolderForLayoutPosition
和 LayoutManager
的 getChildAt
功能。
TL;DR:您可以使用 findViewHolderForAdapterPosition
因为您的 View 绝对适合屏幕并且只要没有太多布局更改。索引将与您的适配器匹配,因此最上面的是 0
.
我做的 Activity 有一个 RecyclerView 和一个按钮,当单击该按钮时,它会在 TextView 中记录 id 为 text1
的文本。 (布局为 android.R.layout.simple_list_item_1
)。由于他们所有的 ID 也相同,因此这应该符合您的要求。适配器有 20 个字符串,从“项目 0”到“项目 19”。
现在请注意 ForLayoutPosition
和 ForAdapterPosition
返回 null
如果 View 未布置在屏幕上。 ForAdapterPosition
的文档中提到的两者之间的区别是吗
Unlike
findViewHolderForLayoutPosition(int)
this method takes into account any pending adapter changes that may not be reflected to the layout yet. On the other hand, ifnotifyDataSetChanged()
has been called but the new layout has not been calculated yet, this method will return null since the new positions of views are unknown until the layout is re-calculated.
因此只有在项目顺序发生变化时,两者的返回才会不同。它可能是交换、删除或添加。任何需要更改布局的内容都会导致两者发生分歧,直到发生布局更改。之后它们再次返回相同的值。
另一方面,LayoutManager
不知道适配器。所以它的位置完全基于布局。
为了通过示例进行演示,假设项目 6 到 16 在我的屏幕上可见,如下所示。这些框是布局边界,我将其设置为可见。
(请注意,在这种情况下,第 17 个 View 尚未加载,但它可能会加载到布局中,而 Item 6 部分可见,因为它可以向上滚动)
在按钮的 onClick
中我记录所有索引的值 0
- 19
在 for 循环中(忽略按钮文本如何显示“第一项”)。 ForAdapterPosition
的结果和 ForLayoutPosition
是指数 0
至 5
和 17
至 19
哪些是离屏返回null
, 而 6
至 16
返回实际的 ViewHolder 对象。从那些,你可以转换到你的自定义 ViewHolder 类并获得所需的 View ,或者做 holder.itemView.findViewById()
.
与此同时,LayoutManager.getChildAt
返回 View
而不是 ViewHolder
.它认为 getChildAt(0)
成为屏幕上的第一项,即 "Item 6"
和 "Item 16"
映射到 getChildAt(10)
.对于指数 11
至 19
, 它返回 null
.
因此,虽然两者都设法在屏幕上获得 11 个可见 View ,但我觉得使用 findViewHolderForAdapterPosition
会更好。因为在大多数情况下它会匹配适配器中项目的位置。
关于android - 检索具有相同 ID 的所有 View ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56599188/