Kotlin、RecyclerView、ViewBinding

Posted

技术标签:

【中文标题】Kotlin、RecyclerView、ViewBinding【英文标题】:Kotlin, RecyclerView, ViewBinding 【发布时间】:2021-11-28 21:48:39 【问题描述】:

我是 Kotlin 编程语言的新手。我对 RecyclerView 和 ViewBinding 有一些疑问。我的英语可能不太好。我对此感到抱歉。但我会尽力解释。如果你能回答我的问题,我会很高兴的。请阅读问题,看图片

1.) 我们将视图提供给 LandmarkHolder 类的构造函数。但是当我们将此视图发送给 RecyclerView.ViewHolder 类的构造函数时,我们会创建 binding.root。

a) 据我所知,我需要“以相同的方式”在 Recycler.ViewHolder 的构造函数中编写 RecyclerViewRowBinding 的对象(我将其编写为绑定)并将其发送到那里。但是为什么我必须写 binding.root 而不是“绑定”?为什么我不能只输入“绑定”?因为绑定本身已经有了设计。

2.) 在制作 Layout Inflater 时,我们通常使用旧方法(R.layout....)访问 XML 文件并对其进行充气,即将其转换为 java 代码。这里的结构发生了变化。当然是再转成java代码了,但是有一个我解决不了的困惑情况:

创建了一个名为 RecyclerRowBinding 的 recycler_row.xml 文件类。

这个类有一个 inflate 方法。我从它的网站上阅读。此外,该类直接引用布局中与其相关的视图的 id。现在卡在我脑海里的是:我在这里膨胀什么?因为在旧的用法(带有finviewbyid)中,我们在编写inflate方法时,是在iflate方法内部添加了一个源xml文件。(如CardView)但是这个新方法没有它。 parent写完后attachtoParent写为False。

3.)我们所说的这个父级代表我的 RecyclerView?

4.) onBindViewHolder 函数中的 holder 对象属于 Landmarkholder 类。所以它使用这个类的属性。但我看到它可以访问一个叫做 itemView 的东西。下面是 ItemView 如何与 Landmarkholder 类相关联。但我正在查看类本身,没有定义与此 itemView 相关的任何内容。这如何到达 itemView?当然,调用itemview的目的是调用context。如果上下文存在于其中,则 itemview 也派生自另一个类。它是从 View 类派生的吗?我想 View 类有这个上下文是对的吗?如何使用“holder”对象调用这个 itemView?

5.) 这个 onCreateViewHolder 返回 LandmarkHolder(binding) 对象。然后需要在其他地方调用此函数才能使其工作。 (当然,通常应该调用它)但是它是从哪里调用的呢?在模拟器本身上?

RecyclerViewAdapterRecycler_row.xmlMainActivity.xml

Why isn't the binding itself a view?

【问题讨论】:

请发布您的代码的实际文本,而不是代码的图片。它使阅读变得更容易,并且回答您的人能够复制粘贴它,并使问题出现在搜索结果中。 【参考方案1】:

我不明白你的所有问题,但也许这个概述会有所帮助。

ViewBinding 采用您的每个 XML 布局并为它们创建一个绑定类,该类由与每个具有 ID 的视图匹配的属性以及另一个名为 root 的属性组成,该属性包含***视图。它还有名为bindinflate 的静态函数。所以如果你有这样的布局:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_
    android:layout_
    android:layout_margin="5dp"
    android:orientation="vertical">

    <TextView
        android:id="@+id/recyclerRowTextView"
        android:layout_
        android:layout_
        android:layout_margin="5dp"
        android:text="Test"
        android:textColor="#0820aa"
        android:textSize="20sp" />
</LinearLayout>

然后它创建一个与此等效的类(在 Java 中,但我将展示 Kotlin 版本,因为这是您正在学习的内容):

class RecyclerRowBinding private constructor(
    val root: LinearLayout,
    val recyclerRowTextView: TextView
) 
    companion object 
        fun bind(view: View): RecyclerRowBinding 
            val root = view as LinearLayout
            val recyclerRowTextView = root.findViewById<TextView>(R.id.recyclerRowTextView)
            return RecyclerRowBinding(root, recyclerRowTextView)
        

        fun inflate(layoutInflater: LayoutInflater): RecyclerRowBinding 
            return inflate(layoutInflater, null, false)
        

        fun inflate(layoutInflater: LayoutInflater, parent: ViewGroup?, attachToParent: Boolean): RecyclerRowBinding 
            val root = layoutInflater.inflate(R.layout.recycler_row, parent, attachToParent)
            return bind(root)
        
    

我没有完全理解你的问题,但有几点需要注意:

它仍然使用 LayoutInflater 从 XML 膨胀视图,就像在没有视图绑定的情况下那样。 绑定本身不是视图类。它只包含对视图的引用。

RecyclerView.ViewHolder 抽象类的构造函数需要一个itemView 对象,它是项目布局的根视图,因此您必须将binding.root 传递给该构造函数。绑定本身不是视图。 RecyclerView.ViewHolder 也有这个itemView 的属性,因此当您创建自己的具有绑定的视图持有者时,有两种不同的方法可以访问根视图,使用holder.binding.rootholder.itemView。但是,binding.root 将是 LinearLayout 类型,itemView 将是不太具体的 ViewGroup

Adapter.onCreateViewHolder() 由 RecyclerView 调用,当它需要显示另一个视图并且没有任何可以回收的先前视图时。

【讨论】:

首先感谢您的回答。我添加了另一个图像。图片中有一个问题。如果你能回答我会很高兴。 你如何打开 RecyclerRowBinding 类?我按 ctrl 单击它,但它会将我定向到此类的 xml 文件。 关于您在图片中的问题,绑定类不能既是视图又是您的特定绑定。例如,布局的根是 LinearLayout 类。绑定是一个包含对您的特定视图的引用的类,因此它不能是 LinearLayout 的实例。此外,绑定类可以绑定到已经创建的布局实例。它们并不是要您检查 binging 类,但是如果您在构建项目后搜索项目的 generated 目录,就可以找到它。 谢谢你的回答,我很难理解,但你帮助了我,非常感谢

以上是关于Kotlin、RecyclerView、ViewBinding的主要内容,如果未能解决你的问题,请参考以下文章

Android Studio(Kotlin)之RecyclerView

Recyclerview没有显示kotlin [重复]

Kotlin 简单的RecyclerView

Kotlin中实现RecyclerView嵌套RecyclerView

Kotlin 中的 RecyclerView itemClickListener [关闭]

Recyclerview 未显示来自 Firebase Kotlin 的数据