通过适配器为每个元素设置自定义 ID 后,如何在 RecyclerView 中找到 ViewById

How to findViewById in RecyclerView after setting custom id to every element via adapter

提问人:Yaroslav Zhuk 提问时间:12/12/2022 最后编辑:Yaroslav Zhuk 更新时间:12/12/2022 访问量:47

问:

我有一个片段,它通过开关实现了 Recycler View。RecyclerView 以 id+=1 的方式为每个开关设置 id。问题是,一旦调用抛出 NullableException,我就无法从这些 ID 中获得任何内容。我知道我必须从父母那里正确地称呼它,但我不明白如何正确地做到这一点。 有代码的结构: 使用 ConstraintLayout(R.id.settingsScreen) -> RecylerView(R.id.recyclerView) 的片段,该片段使用开关 (R.id.switch) 创建 LinearLayouts(R.id.settingLayout)。

class ViewHolder{
    val l : LinearLayout = view.findViewById(R.id.settingLayout)
}

if (holder.l.findViewById<SwitchCompat>(1100).isActivated){..}

抛出java.lang.NullPointerException: Attempt to invoke virtual method 'boolean androidx.appcompat.widget.SwitchCompat.isActivated()' on a null object reference

Kotlin android-recyclerview nullpointerexception findViewById

评论


答:

0赞 lotaviods 12/12/2022 #1

可以使用 itemView 属性获取视图

不确定您是否在尝试执行自定义 ID。


您可以使用 itemView 获取 viewHolder 膨胀的所有视图。

在 ViewHolder 构造函数中将视图作为参数传递后,此属性将赋予 ViewHolder,然后 ViewHolder 将根据视图的 ID 膨胀视图。

您可以通过以下方式在 ViewHolder 中查看:

itemView.findViewById<LinearLayout>(R.id.settingLayout)

itemView.findViewById<SwitchCompat>(R.id.switch)

您可以在 google docs 中查看更多选项

如果这些不是您要求的,请告诉我

评论

0赞 Yaroslav Zhuk 12/12/2022
不幸的是,它没有帮助。通过自定义 id,我的意思是在 var id 的帮助下为 OnBindViewHolder 中的每个开关设置 id:1100;id++。在我的应用程序中,我需要检查 1100/1101/1102/1103 是否被激活,但它总是抛出 NullPointerException,尽管它们都有自己的 ID(使用 holder.switch.setOnClickListener{Log.d(“x”, “${item.id}”)} 检查)
0赞 lotaviods 12/12/2022
您能找到一些以编程方式设置 id 或按数字设置的示例吗?
0赞 Yaroslav Zhuk 12/12/2022
是的,它在我的应用程序中的一个地方工作,但在另一个地方不起作用。但是,我发现设置自定义 ID 是一种不好的做法,因此我将删除它们并尝试以另一种方式进行设置。谢谢你的帮助
1赞 Tenfour04 12/12/2022 #2

像这样自己创建视图 ID 是非常脆弱的。它们很容易与 Android build 生成的 ID 发生冲突。因此,如果您创建 ID,您应该使用 ViewCompat.generateViewId() 来安全地执行此操作。

但这是您通常首先要避免的事情。它很慢。这就是提供视图绑定的原因,用于缓存视图,这样您就不必继续搜索它们。findViewById

我强烈建议将视图存储在集合中,而不是为它们分配 ID。然后,您可以在需要时有效地从集合中提取它们。您只需要确保在完成视图时对集合进行垃圾回收(不要创建比视图所在的屏幕更长的集合)。

评论

0赞 Yaroslav Zhuk 12/12/2022
好吧,我承认使用 ids 是个坏主意。感谢您的回答,我将更改我的代码以与使用适配器的更好变体相对应。(不知不觉,我不能提升你的名声,但我真诚地感谢你)