【问题标题】:Multiple instances of same fragment type with different ViewModel type based on argument passed to fragment基于传递给片段的参数,具有不同 ViewModel 类型的相同片段类型的多个实例
【发布时间】:2020-05-09 01:20:24
【问题描述】:

我有 ViewPager2 的应用程序。其中的所有页面都是相同类型片段的实例。所有页面都在回收视图中显示不同数据类型的一些列表。使用 Retrofit 调用从某个 API 端点填充数据。

我正在使用 dagger 2 来注入视图模型。

一页一切正常。现在我想创建其他页面,我在问是否有任何方法/模式来实现其他页面而不创建不同的片段类,但只能使用不同的 viewModel 类型?

也许是一些通用的 viewModel 或其他东西。

【问题讨论】:

  • 如果视图页面的屏幕之间的逻辑足够通用,那么通用视图模型更有意义。然后,您可以拥有子视图模型,它们只是将不同的依赖项传递给通用视图模型的构造函数,并且可能会在必要时覆盖某些功能。从片段中,您可以基于片段在创建片段时采用的某些参数/类别来创建视图模型。绝对有可能。您需要在lists in a recyclerview, of different data types 上提供更多详细信息。

标签: android retrofit dagger-2 android-viewmodel android-viewpager2


【解决方案1】:

页面类型

enum class PageType {
    Page1, Page2, Page3;
}

val PageType.viewModelClass: KClass<out GenericViewModel>
    get() = when (this) {
        PageType.Page1 -> Page1ViewModel::class
        // todo
    }

视图模型

abstract class GenericViewModel<T>() : BaseViewModel() {

    abstract val pageType: PageType
}

class Page1ViewModel @Inject constructor() : GenericViewModel() {
    override val pageType: PageType = PageType.Page1
}

片段

class PageFragment : BaseFragment() {

    private val pageType: PageType by lazy {
        TODO("read from arguments bundle")
    }

    private val vm: GenericViewModel by lazy {
        ViewModelProvider(this, viewModelFactory).get(pageType.viewModelClass.java)
    }

    companion object {
        fun newInstance(type: PageType): PageFragment {
            TODO("add type into bundle and set as arguments")
        }
    }
}

如果您当前的 dagger 设置适用于视图模型,那么您无需执行任何特殊操作即可支持此模式。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-11-05
    • 2020-11-19
    • 2011-08-05
    • 2018-09-15
    相关资源
    最近更新 更多