Android 在视图模型中启动片段

Android 在视图模型中启动片段,android,android-fragments,kotlin,mvvm,data-binding,Android,Android Fragments,Kotlin,Mvvm,Data Binding,我正试图重新设计我的研究项目,以使用MVVM和数据绑定 项目在这里: 在返工之前,应用程序的行为如下: main活动承载一个CrimeListFragment,它是Crimes的回收视图 CrimeHolder实现查看。OnClickListener和onClick()使用一个回调函数,该函数的id为已单击的Crime main活动实现回调函数,并使用supportFragmentManager 这种行为可以在分支主控中看到 现在,在返工时,我已经做到了: list\u item.xml使

我正试图重新设计我的研究项目,以使用MVVM和数据绑定

项目在这里:

在返工之前,应用程序的行为如下:

  • main活动
    承载一个
    CrimeListFragment
    ,它是
    Crime
    s的回收视图
  • CrimeHolder
    实现查看。OnClickListeneronClick()使用一个回调函数,该函数的
    id
    为已单击的
    Crime
  • main活动
    实现回调函数,并使用
    supportFragmentManager
  • 这种行为可以在分支主控中看到
现在,在返工时,我已经做到了:

  • list\u item.xml
    使用数据绑定
  • crimevewmodel
    拥有财产
    crime:crime
  • 我在
    CrimeListFragment
    onCreateView()中膨胀绑定
  • crimehold
    类具有
    init{binding.viewModel=CrimeViewModel()}
  • CrimeHolder
    也有
    bind(crime:crime)
    ,在那里我将
    crime
    分配给
    viewModel
    crime
  • CrimeListAdapter
    类自解释
  • 这种行为可以在链接的分支dev中看到
RecyclerView中的每个犯罪都是可点击的,这意味着
列表项。xml
将具有
android:onClick=“@{()->viewModel.onCrimeClicked()}”
crimevewmodel
将具有一个函数
onCrimeClicked()

我的问题是:在遵守MVVM体系结构的同时,如何从viewmodel的
onClicked()
启动新片段(
crimedtailfragment

我可以像以前一样简单地在Holder中实现视图。OnClickListener,但是使用MVVM,我应该避免视图中的逻辑(
CrimeListFragment


还有一个问题-我还应该实施哪些其他更改来提高MVVM?

IMO,,我将在活动或片段中创建一个lambda块,并将一个lambda块传递给适配器,如下所示:

private val onCrimeClicked: (Crime) -> Unit = {
    // This will be triggered later
}
private val crimeListAdapter = CrimeListAdapter(onCrimeClicked)
在适配器内部,将相同的lambda块传递给CrimeHolder的构造函数,在该构造函数中在onCreateViewHolder()内创建新的CrimeHolder

然后,您的CrimeHolder类可能如下所示:

class CrimeHolder(private val onCrimeClicked: (Crime) -> Unit = {}){

    fun bind(crime : Crime){
        list.setOnClickListener{
            onCrimeClicked(crime)
        }
    }
}
看看这是否适合你的需要


PS:这样你就不会违反MVVM规则。

MVVM体系结构的要点是将ViewModel的关注点与实际视图本身分开,因此从ViewModel中打开片段将是一个错误的选择。相反,当单击回收器视图中的犯罪时,您应该更改viewmodel中所选犯罪的值,例如
viewmodel.setSelectedCrime(selectedCrime)
。然后,您的主要活动应该是观察您的viewModel,当
selectedCrime
发生更改时,它应该启动
CrimedDetailFragment
@RyanSaffer ok,这样我就在viewModel类中设置了一个LiveData属性。现在我还不太清楚我应该如何开始在活动中观察。MainActivity如何获得
list\u item\u crime.xml
所使用的
binding.viewModel
?另外,我不太清楚您所说的是哪个viewModel。每个RecyclerV项目都有自己的viewmodel,因此我无法观察每个项目。因此,如果您的意思是
CrimeListViewModel
,那么我不清楚片段如何知道选择了哪个项。因此,如果我理解正确,在适配器类中,我创建了一个使用回调的函数属性,然后我创建了一个以该函数属性为参数的保持器。Holder然后创建一个ViewModel实例,并将该函数属性作为参数,最后ViewModel的onClick()使用该函数。对的确保我正确理解了您,因为虽然代码似乎在我这边工作,但可能我没有正确理解您,我的代码可能会违反MVVM准则。