如何在 2020/21 中获取 activity 中的 ViewModel 实例?

How to get an Instance of ViewModel in activity in 2020/21?

我是 mvvm 模式的新手。我为主要 activity 创建了一个 ViewModel。现在我想在主 activity 中获取 ViewModel 的一个实例。

Whosebug 上的大多数教程和答案都建议使用 ViewModelProviders.of(...,但这已被弃用。

所以根据 Whosebug 上的这个问题: main activity in onCreate,我做了以下操作(我可以发誓我已经有了它 运行):mainActivityViewModel = new ViewModelProvider(this).get(MainActivityViewModel.class);

但是,我收到一条错误消息,告诉我没有找到合适的构造函数。

error: no suitable constructor found for ViewModelProvider(MainActivity)

或者为了完全清楚,MainActivity 应该是 ViewModelStoreOwner,我创建了一个变量 ViewModelStoreOwner vmso = this; 并将该变量放入构造函数中,如下所示: mainActivityViewModel = new ViewModelProvider(vmso).get(MainActivityViewModel.class);

ViewModel viewModel = ViewModelProviders.of(this).get(ViewModel.class);

Android 支持库版本已贬值。因此,您需要确保导入 Androidx。并且你需要在 Gradle 文件中实现 androidx 依赖。

不建议使用 "new" 关键字创建新的 ViewModel 对象。

Duplicate question and already answered here

只需替换:

这个:

boardViewModel = ViewModelProviders.of(this).get(BoardViewModel::class.java)

有了这个:

boardViewModel = ViewModelProvider(this).get(BoardViewModel::class.java)

目前,唯一对我有用的是使用: MainActivityViewModel = new ViewModelProvider(this, new ViewModelProvider.NewInstanceFactory()).get(MainActivityViewModel.class);

但是,我仍然感谢任何建议,如何使用 new ViewModelProvider(this).get(MainActivityViewModel.class);

来做不同的事情

您应该将 gradle 文件更新为:

implementation 'androidx.lifecycle:lifecycle-extensions:2.2.0'

并且由于此更改,您可以将 Activity 传递给您提到的构造函数:

mainActivityViewModel = new ViewModelProvider(this).get(MainActivityViewModel.class);

您可以使用 ViewModelFactory:

val viewModelFactory = VMFactory(requireActivity().application)
viewModel= ViewModelProvider(requireActivity(),viewModelFactory).get(MainViewModel::class.java)

VMFactory 代码:

class VMFactory(application: Application) : ViewModelProvider.NewInstanceFactory() {

    val _application: Application=application

    @NonNull
    override fun <T : ViewModel?> create(@NonNull modelClass: Class<T>): T {
            return  MainViewModel(_application) as T
    }
}

请注意,我的 MainViewModel 扩展了 AndroidViewModel,因此需要应用程序作为输入参数。

在您的应用中使用 Fragment-ktx libr,您可以获得如下视图模型

第一次更新Gradle 文件为应用程序 -> build.gradle

implementation 'androidx.fragment:fragment-ktx:1.1.0'

// 在ActivityFragment中获取ViewModel as

private val viewModel: MainActivityViewModel by viewModels()

// 如果你想在 ChildFragment 中获得与 ViewModel 相同的实例

 private val viewModel: MainActivityViewModel by viewModels(
    ownerProducer = { requireParentFragment() }
)

在 Activities 中使用 val viewModel by viewModels<TheViewModel>() 并在片段中使用 val viewModel by activityViewModels<TheViewModel>() 从 activity 中获取相同的视图模型(因此共享视图模型)。

现在是 androidx 的一部分

以新方式获取 ViewModel

MainActivityViewModel mainActivityViewModel;
    mainActivityViewModel= new ViewModelProvider(this).get(MainActivityViewModel.class);

我遇到了类似的问题,最后发现我错过了 class 中的“extends ViewModel”定义,所以它应该是这样的:

public class ViewModelClass extends ViewModel
{
    // Tracks the score for Team A
    public int scoreTeamA = 0;

    // Tracks the score for Team B
    public int scoreTeamB = 0;
}

根据 Android 文档,您可以这样做:

KOTLIN

implementation 'androidx.activity:activity-ktx:1.3.1'

val model: MyViewModel by viewModels()

JAVA

implementation 'androidx.lifecycle:lifecycle-extensions:2.1.0'

MyViewModel model = new ViewModelProvider(this).get(MyViewModel.class);