android-fragments 如何在属于两个不同活动的片段之间共享视图模型

hc2pp10m  于 2022-11-13  发布在  Android
关注(0)|答案(2)|浏览(141)

我试图理解如何在不同的片段(甚至属于不同的活动)之间使用相同的视图模型。
因此,假设我有包含片段A、片段B的Activity 1和包含片段C的Activity 2。如何创建一个可以在所有这些片段中使用的视图模型示例?
我试着理解共享视图模型,但似乎它是用于在单个活动的片段之间共享数据,而不是多个活动。
因此,基本上我想创建一个跨所有片段的视图模型的示例?我如何才能实现这个功能,同时记住MVVM方法。
任何帮助都将不胜感激。谢谢!

1dkrff03

1dkrff031#

This is not supported. Google的建议是将所有屏幕放在一个Activity中。
但是,您可以创建一个ViewModel的每个示例都使用的中间单例类。
或者你可以使用一个工厂,把它当作一个临时的单例处理,并进行引用计数,这样它就不会过早地被清除,或者挂在引用上太久。

private var viewModelInstance: MyViewModel? = null
private var refCount = 0

class MyViewModel: ViewModel() {

    override fun onCleared() {
        if (--refCount > 0) {
            return
        }
        viewModelInstance = null
        
        // Do typical onCleared cleanup here
    }
}

class MyViewModelFactory: ViewModelProvider.Factory {
    @Suppress("UNCHECKED_CAST")
    override fun <T : ViewModel> create(modelClass: Class<T>): T {
        require(modelClass.isAssignableFrom(MyViewModel::class.java)) { "Factory only supports MyViewModel" }
        refCount++
        viewModelInstance = viewModelInstance ?: MyViewModel()
        return viewModelInstance as T
    }
}
hi3rlvi2

hi3rlvi22#

不支持在多个活动之间共享视图模型
实现这一点的一种方法是使用AndroidViewModel。您可以创建一个ViewModel扩展AndroidViewModel。这需要应用程序示例。此视图模型将绑定到应用程序生命周期,并且在应用程序的整个生命周期中都可以使用相同的示例。在一个Activity中,您可以添加数据、而在其他活动中你可以得到更新的数据。这将是类似于单例示例的行为(但不完全是)。
除此之外,如果您使用带有Activity/fragment生命周期所有者的观察器,您还可以在AndroidViewModel中使用实时数据。因此,观察器将仅在fragment或Activity的生命周期之前处于活动状态。

视图模型:

class AppViewModel constructor(private val mApplication: Application) :
        AndroidViewModel(mApplication) {
     //ViewModel Logic
    }

**正在初始化视图模型:**您可以在任何片段或Activity中像这样初始化视图模型。

val appViewModel = ViewModelProvider.AndroidViewModelFactory.getInstance(MyApp.getInstance())
            .create(AppViewModel::class.java)

应用程序类别:

class MyApp : Application() {
    override fun onCreate() {
        super.onCreate()
    mInstance = this
}

    companion object {    
        lateinit var mInstance: CooperApp

        @Synchronized
        fun getInstance(): MyApp {
            return mInstance
        }
    }
}

我们还可以使用的一个功能是在应用程序类中初始化viewmodel,并创建与getInstance()类似的函数,该函数将返回viewmodel示例,并在整个应用程序中使用它

相关问题