如何解决与 RecyclerView 的数据绑定不呈现正确性
我正在尝试将数据绑定与 RecyclerView 结合使用。我设置了一个简单的应用程序,它在 RecyclerView 中显示数字 1 到 50,每行一个。我想对每一行使用数据绑定。
这是我的适配器的代码(注意我调用了 dataBinding.executePendingBindings()
):
class SimpleAdapter
: ListAdapter<Int,SimpleAdapter.SimpleAdapterViewHolder>(SimpleAdapterDiffUtil()) {
inner class SimpleAdapterViewHolder(
private val dataBinding: SimpleAdapterViewHolderBinding
) : RecyclerView.ViewHolder(dataBinding.root) {
fun bind(str: String) {
Log.e("MYTAG","setting TextView: $str")
dataBinding.txtView.text = str
dataBinding.executePendingBindings()
}
}
override fun onCreateViewHolder(parent: ViewGroup,viewType: Int): SimpleAdapterViewHolder {
val binding = SimpleAdapterViewHolderBinding.inflate(
LayoutInflater.from(parent.context),parent,false)
return SimpleAdapterViewHolder(binding)
}
override fun onBindViewHolder(holder: SimpleAdapterViewHolder,position: Int) {
val stringValue = getItem(position)
holder.bind(stringValue.toString())
}
}
private class SimpleAdapterDiffUtil: DiffUtil.ItemCallback<Int>() {
override fun areItemsTheSame(oldItem: Int,newItem: Int): Boolean {
return oldItem == newItem
}
override fun areContentsTheSame(oldItem: Int,newItem: Int): Boolean {
return oldItem == newItem
}
}
这是视图 XML
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<data>
<variable
name="text"
type="String" />
</data>
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:id="@+id/txt_view"
android:text="@{text}"
android:layout_width="match_parent"
android:layout_height="36dp" />
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="@color/black"
app:layout_constraintTop_toBottomOf="@id/txt_view"
/>
</androidx.constraintlayout.widget.ConstraintLayout>
</layout>
这是它的作用:
如您所见,在初始屏幕中,没有任何行未正确呈现。当我向下滚动时,我发现它是从第 23 行开始渲染的。然后再向上滚动,我终于可以看到前面的行被填充了。
如果我将代码更改为使用普通的旧视图而不是数据绑定,它会按预期工作。代码在这里:
// This works fine!
class SimpleAdapter
: ListAdapter<Int,SimpleAdapter.SimpleAdapterViewHolder>(SimpleAdapterDiffUtil()) {
inner class SimpleAdapterViewHolder(
private val rootView: View
) : RecyclerView.ViewHolder(rootView) {
fun bind(str: String) {
Log.e("MYTAG","setting TextView: $str")
rootView.findViewById<TextView>(R.id.txt_view).text = str
}
}
override fun onCreateViewHolder(parent: ViewGroup,viewType: Int): SimpleAdapterViewHolder {
val rootView = LayoutInflater.from(parent.context)
.inflate(R.layout.simple_adapter_view_holder,false)
return SimpleAdapterViewHolder(rootView)
}
override fun onBindViewHolder(holder: SimpleAdapterViewHolder,newItem: Int): Boolean {
return oldItem == newItem
}
}
解决方法
正如我在您的 xml 中看到的,您正在设置 android: text="@{text}"
换句话说,textView 值是从 binding.text
设置的
您设置 dataBinding.txtView.text = str
它将更新文本。在使用 executePendingDataBinding
之后,它的值将重置为 null 或空的 dataBinding.text
(又名 android: text="@{text}"
)。所以你应该设置
dataBinding.text = str
代替
dataBinding.txtView.text = str
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。