使用数据绑定时如何在适配器中绑定 viewModel

Posted

技术标签:

【中文标题】使用数据绑定时如何在适配器中绑定 viewModel【英文标题】:How to Bind viewModel in adapter while using databinding 【发布时间】:2021-12-25 03:43:48 【问题描述】:

song_item.xml

<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">

<data>
    <variable
        name="song"
        type=".models.Song" />

    <variable
        name="viewModel"
        type=".SongDetailViewModel" />
  </data>

  <TextView
   android:id="@+id/txt_song_name"
   android:layout_
   android:layout_     
   app:selected="@safeUnbox(viewModel.currentData.id == song.id)"
   />

</layout>

SongAdapter.kt

我正在寻找一种将 song_item 中的 viewModel 绑定到我的适配器的方法。

我需要初始化 SongDetailViewModel

在片段中我可以做到:

private val viewModel: SongDetailViewModel by viewModels()

但是我将如何在我的适配器中做到这一点:

class SongAdapter(
) : RecyclerView.Adapter<RecyclerView.ViewHolder>() 

 inner class ViewHolderSong(private val binding: ViewDataBinding) :
    RecyclerView.ViewHolder(binding.root), View.OnClickListener 

     private fun bindSong(song: Song) 
        binding as SongItemBinding
        binding.apply 
            this.song = song
            this.viewModel = songDetailViewModel <--- here, I don't know how to initialize this viewModel inside the adapter
            executePendingBindings()
            rootLyt.setOnClickListener(this@ViewHolderSong)
            icMore.setOnClickListener(this@ViewHolderSong)
        
    
   
  

【问题讨论】:

为什么要在这里传递一个视图模型?视图模型的范围应该是片段/导航图/活动。您不会(也不需要)在适配器中获得 ViewModel 的任何好处。如果你真的需要,只需传递一个简单的 kotlin 类。否则,您可以只从适配器发出事件并在片段/活动或它们的视图模型中处理它们。 【参考方案1】:

您应该将在片段中创建的viewModel 作为参数发送到SongAdapter。之后,您可以将其绑定到song_item

也不要忘记将lifecycleOwner 设置为您的歌曲项绑定,以便正确观察更改。您也应该通过参数将其发送到SongAdapter

您的SongAdapter 应该是这样看待一天结束的:

class SongAdapter(
    private val viewModel: SongDetailViewModel,
    private val lifecycleOwner: LifecycleOwner
) : RecyclerView.Adapter<RecyclerView.ViewHolder>() 

    inner class ViewHolderSong(private val binding: ViewDataBinding) :
        RecyclerView.ViewHolder(binding.root), View.OnClickListener 

        private fun bindSong(song: Song) 
            binding as SongItemBinding
            binding.apply 
                this.song = song
                this.viewModel = viewModel
                this.lifecycleOwner = lifecycleOwner
                executePendingBindings()
                rootLyt.setOnClickListener(this@ViewHolderSong)
                icMore.setOnClickListener(this@ViewHolderSong)
            
        
    

【讨论】:

以上是关于使用数据绑定时如何在适配器中绑定 viewModel的主要内容,如果未能解决你的问题,请参考以下文章

将多个类的数据绑定到单个列表视图/xamarin 表单

如何使用 Kotlin 在 RecyclerView Adapter 中实现 onClick 并进行数据绑定

数据表和绑定源/数据适配器之间的区别?

数据绑定 recyclerview 适配器从 livedata 接收到空列表

wpf绑定--学习笔记2

使用数据绑定填充 RecyclerView 内的 MultiView ViewHolder