访问 Recycler´s Adapter 中的 ViewModel

Posted

技术标签:

【中文标题】访问 Recycler´s Adapter 中的 ViewModel【英文标题】:visit ViewModel in Recycler´s Adapter 【发布时间】:2021-10-23 07:18:32 【问题描述】:

我遇到的问题是,我想在 RecyclerView 的适配器中访问我的 ViewModel,但我有一个例外: “您的活动尚未附加到应用程序实例。您不能在 onCreate 调用之前请求 ViewModel”

class FoodInSortAdapter( val activity:MainActivity,private val list:List<String>):RecyclerView.Adapter<FoodInSortAdapter.Holder>() 

    val viewModel :FoodViewModel by lazy 
        println("servus")
        ViewModelProvider(activity).get(FoodViewModel::class.java)

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): Holder 
        val view = LayoutInflater.from(parent.context).inflate(R.layout.sortitem, parent, false)
        return Holder(view)
    


    override fun onBindViewHolder(holder: Holder, position: Int) 
        holder.sortName.text = list[position]
        holder.itemView.setOnClickListener 
            val m=list[position]
            viewModel.setQuery(m)
        
    

有人知道这是怎么回事吗?

谢谢

【问题讨论】:

发布您的问题时。直接贴代码sn-p。其他人会更容易,你会得到更快的答案。 @CodeWithVikas,感谢您的建议,刚到这里。你是说 CodeSample 还是 BlockQuote? 两者都可以。 【参考方案1】:

首先,您不应该在 Activity 或 Fragment 之外初始化 viewModel。

我假设您不在onCreate 中创建适配器,而是在初始化阶段。有两种解决方案可以解决您的问题。

    在activity中初始化vm,并通过新增加的方法setupViewModel在adapter中设置,在onCreate中调用。这样更好。
class FooActivity : Activity

  private val viewModel: FoodViewModel by lazy 
        println("servus")
        ViewModelProvider(activity).get(FoodViewModel::class.java)
  

  private val adapter = FoodInSortAdapter(emptyList())

  override fun onCreate(savedInstanceState: Bundle?) 
        super.onCreate(savedInstanceState)
        adapter.setupViewModel(viewModel)
  



class FoodInSortAdapter(private val list:List<String>):RecyclerView.Adapter<FoodInSortAdapter.Holder>() 

    private lateinit var viewModel: FoodViewModel

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): Holder 
        val view = LayoutInflater.from(parent.context).inflate(R.layout.sortitem, parent, false)
        return Holder(view)
    


    override fun onBindViewHolder(holder: Holder, position: Int) 
        holder.sortName.text = list[position]
        holder.itemView.setOnClickListener 
            val m=list[position]
            viewModel.setQuery(m)
        
    

   fun setupViewModel(vm: FoodViewModel)
      viewModel = vm
   

    onCreate 方法中创建适配器,这也应该适用于您。

干杯

【讨论】:

首先使用observe方法获取模型数据并放入列表,然后传递给recyclerview。 @Rabbit 想要传递 viewModel 来调用 setQuery,而不仅仅是将数据作为列表传递 嗨,是的,我想在 VM 中调用 setQuery 方法。这会触发另一个网络 - 使用此参数 m 进行查询,(我点击一个 recyclerView) @JakubPruszyński,对不起,我不太明白你的第一个建议。看起来很酷 :) 任何例子 :> @Rabbit 我已根据您的问题用示例更新了帖子

以上是关于访问 Recycler´s Adapter 中的 ViewModel的主要内容,如果未能解决你的问题,请参考以下文章

Recycler VIew 和 Adapter 打开内容不同的Activity

在 FireStore Ui Recycler Paging Adapter 中使用 Paging 3 时出错:PagingConfig 无法转换为 Config

如何在 kotlin 的 Recycler View Adapter 中添加更多数据列表而不清除先前的数据?

通过单击单个项目选择Recycler视图中的所有项目

RecyclerView 知识梳理 - Adapter

Recycler多布局(适配器)之有Type值