如何让视图绑定与 RecyclerView.ViewHolder 中的 XML 布局高度一起使用,就像他们对 Kotlin Synthetics 所做的那样?

Posted

技术标签:

【中文标题】如何让视图绑定与 RecyclerView.ViewHolder 中的 XML 布局高度一起使用,就像他们对 Kotlin Synthetics 所做的那样?【英文标题】:How to get view binding to work with XML layout heights in RecyclerView.ViewHolder like they did with Kotlin Synthetics? 【发布时间】:2021-12-29 18:49:46 【问题描述】:

在尝试将应用程序从已失效的 Kotlin 合成转换为更新的/受支持的视图绑定方法时,我遇到了这个问题,其中布局被夸大,但 layout_height 在夸大的布局中被忽略。结果是一个看起来不太好的皱缩视图。

    inner class InfoAdapter(val data: Array<String>) : androidx.recyclerview.widget.RecyclerView.Adapter<androidx.recyclerview.widget.RecyclerView.ViewHolder>() 
        private val header = 0
        private val item = 1
        private var clickListener: RecyclerClickListener? = null

        override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): androidx.recyclerview.widget.RecyclerView.ViewHolder 
            when (viewType) 
                item -> return ItemVH(StringRowBinding.inflate(layoutInflater))
                header -> return HeaderVH(InfoHeaderBinding.inflate(layoutInflater))
            

            return ItemVH(StringRowBinding.inflate(layoutInflater))
        

...

        inner class ItemVH(private val binding: StringRowBinding): androidx.recyclerview.widget.RecyclerView.ViewHolder(binding.root) 
            init 
                itemView.setOnClickListener  v ->
                    clickListener?.itemClicked(v, adapterPosition)
                
            
            fun bind(text: String) 
                binding.title.text = text
            
        

...
    

string_row.xml:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_
    android:layout_
    android:background="?android:attr/selectableItemBackground">

    <TextView
        android:id="@+id/title"
        android:layout_
        android:layout_
        android:layout_centerVertical="true"
        android:layout_gravity="center_vertical"
        android:layout_marginLeft="16dp"
        android:layout_marginStart="16dp"
        android:layout_marginRight="16dp"
        android:layout_marginEnd="16dp"
        android:textAppearance="@style/TextAppearance.AppCompat.Body2"/>

</RelativeLayout>

相对布局的高度应该是 48dp,但似乎该属性被忽略了。数据确实显示,并且布局高度属性在 Kotlin 合成中工作得很好。

我找到了this SO question related to Activity + view binding,但没有针对 ViewHolder + 视图绑定的特定内容。与该问题的公认答案相关的是反问:如果它只是要忽略边距、高度和膨胀布局的宽度和“修复”基本上是根本不使用inflater() 调用而只使用findViewById()?也就是说,被接受的答案大多违背了使用视图绑定器膨胀视图的目的,并重新引入了findViewById()。无论如何,如何使特定答案适应这种情况并不明显。

【问题讨论】:

【参考方案1】:

问题是您使用了inflate() 的重载,它没有指定父视图。执行此操作时,根视图上的任何 layout_ 属性都将被忽略(并替换为默认值)。试试这个:

override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): androidx.recyclerview.widget.RecyclerView.ViewHolder 
    when (viewType) 
        item -> return ItemVH(StringRowBinding.inflate(layoutInflater, parent, false))
        header -> return HeaderVH(InfoHeaderBinding.inflate(layoutInflater, parent, false))
    

    return ItemVH(StringRowBinding.inflate(layoutInflater, parent, false))

确保将false 作为第三个参数传递; RecyclerView 本身将管理将子视图附加到父视图。

【讨论】:

以上是关于如何让视图绑定与 RecyclerView.ViewHolder 中的 XML 布局高度一起使用,就像他们对 Kotlin Synthetics 所做的那样?的主要内容,如果未能解决你的问题,请参考以下文章

如何让我的 WPF 用户控件的依赖属性更新我的视图模型?

如何预览包含与其父视图状态绑定的视图?

SwiftUI如何让绑定到同一个状态的多个TextField呈现出不同输入行为

SwiftUI如何让绑定到同一个状态的多个TextField呈现出不同输入行为

如何绑定列表视图

如何将视图绑定与线性布局一起使用?