【问题标题】:Reusing Fragments/Bottomsheets with viewModel as data binding variable使用 viewModel 作为数据绑定变量重用 Fragments/Bottomsheets
【发布时间】:2020-09-18 00:56:40
【问题描述】:

我将举一个例子,以便于解释我的问题。

考虑在我的应用中使用FragmentAViewModelAFragmentBViewModelB

我有一个BottomSheetSample 用于FragmentAFragmentB 由于底部工作表的作用很小,比如选择一个值,我想共享底部工作表所在片段的 ViewModel正在显示,而不是拥有单独的 ViewModel 并将数据传输到 fragmentViewModel。我正在将这样的ViewModel 绑定到导航图。

内部FragmentA

private val viewModel: ViewModelA by navGraphViewModels(R.id.nav_A_graph) { viewModelFactory }

内部BottomSheetSample

private val viewModel: ViewModelA by navGraphViewModels(R.id.nav_A_graph) { viewModelFactory }

我像这样将ViewModel 传递给XML,以便将它与数据绑定一起使用:

val binding: BottomSheetSampleBinding =
            DataBindingUtil.inflate(inflater, R.layout.bottomSheet, container, false)
binding.viewModel = viewModel

示例底部表单 XML:

<?xml version="1.0" encoding="utf-8"?>
<layout>

    <data>

        <variable
            name="viewModel"
            type="com.ui.fragmenta.ViewModelA" />
    </data>
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content">
        <Button
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:onClick="@{()->viewModel.oneSelected()} />
        <Button
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:onClick="@{()->viewModel.twoSelected()} />
    </LinearLayout>
</layout>

现在的问题是我还必须在FragmentB 中使用相同的底页(BottomSheetSample)。由于我将ViewModel 传递给XML 进行数据绑定,因此我无法使用与当前BottomSheetSampleBinding 期望ViewModelA 的对象相同的底部工作表。

所以我最终要做的是创建一个新的BottomSheetSampleB,它与BottomSheetSample 完全相同,只需将新XML 中的ViewModel 更改为ViewModelB

<?xml version="1.0" encoding="utf-8"?>
<layout>

    <data>

        <variable
            name="viewModel"
            type="com.ui.fragmentb.ViewModelB" />
    </data>
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content">
        <Button
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:onClick="@{()->viewModel.oneSelected()} />
        <Button
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:onClick="@{()->viewModel.twoSelected()} />
    </LinearLayout>
</layout>

现在,如果我必须在第三个片段中使用相同的 BottomSheet,我必须复制 BottomSheetSample 并再次执行整个操作。这看起来是多余的,因为同一张底片被一次又一次地复制。但我不知道如何避免这样做。有人能告诉我正确的方法吗?

希望我清楚我的问题。

【问题讨论】:

    标签: android mvvm data-binding android-viewmodel


    【解决方案1】:

    创建一个 BaseViewModel(任何名称)并将底部工作表所需的所有内容保存在 BaseViewModel 中。在底部表中使用此 BaseViewModel

    <layout>
    
        <data>
    
            <variable
                name="viewModel"
                type="com.ui.fragmentb.BaseViewModel" />
        </data>
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content">
            <Button
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:onClick="@{()->viewModel.oneSelected()}" />
            <Button
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:onClick="@{()->viewModel.twoSelected()}" />
        </LinearLayout>
    </layout>
    

    使用BaseViewModel 扩展您的ViewModelA,ViewModelB

    【讨论】:

    • 感谢您的回答。让我试试,然后回复你
    • 谢谢 Manohar.. 我一辈子都想不通为什么我没有想到这个。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-09-21
    • 1970-01-01
    • 1970-01-01
    • 2016-09-07
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多