使用 Hilt 注入 viewModel

3
我希望使用Hilt将我的viewModel注入RecyclerView中。 可以注入,但是当recyclerView被销毁时viewModel没有被销毁。 使用Hilt在RecyclerView中注入viewModel的最佳方法是什么?

您是否正在尝试将ViewModel注入到RecyclerView适配器中?如果是,使用案例是什么? - Abhimanyu
是的,我想在RecyclerView适配器中添加viewModel。 在我的情况下,我希望每个RecyclerView适配器都有自己的viewModel, 这样我们就可以在片段中观察viewModel对象。 - Mehdi Shojaeian
理想情况下,不应该出现这种情况。请解释您的用例。 - Abhimanyu
我们想要在Fragment中检测行点击,但是我们的RecyclerViewAdapter在应用程序中被多处重用。 - Mehdi Shojaeian
Viewmodel 不应该被注入到适配器中。无论你想要实现什么,都有更好的方法来实现它。 - Andrew
你的解决方案是什么? - Mehdi Shojaeian
2个回答

1

最好的方法是创建单独的适配器和视图持有者类,然后您可以将viewModel注入到该视图持有者类中,而不是适配器中。 要销毁viewModel,您应该通过观察parentlifecycle手动执行它。当父生命周期事件为ON_DESTROY时,在适配器类的init块中执行类似于以下内容的操作。

parentLifecycle.addObserver(object : LifecycleObserver {

            @OnLifecycleEvent(Lifecycle.Event.ON_DESTROY)
            fun onParentDestroy() {
                recyclerView?.run {
                    for (i in 0 until childCount) {
                        getChildAt(i)?.let {
                            (getChildViewHolder(it) as BaseItemViewHolder<*, *>)
                                .run {
                                    onDestroy()
                                    viewModel.onManualCleared()
                                }
                        }
                    }
                }
            }
  }

这里的onManualCleared()函数调用了onCleared()函数。


0
一个视图模型不应该被注入到适配器中,正如我在评论中所读到的,你可以使用更好的方法来代替它。
假设你有一个包含许多行的适配器,每一行当用户点击它时,都会执行一个网络调用。
首先,创建一个接口。
interface Click {
fun onClick(index: Int, item: Model)
}

在你的适配器中,初始化一个实例,然后在onBindViewHolder中使用它。
yourview.setOnClickListener {v-> interface.onClick()}

不要忘记在使用它的地方(Activity / Fragment / ...)初始化接口。
这比为每一行使用ViewModel的解决方案更好,因为后者可能会导致SystemLeaks。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接