简体   繁体   English

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

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

I am new to the mvvm pattern.我是 mvvm 模式的新手。 I created a ViewModel for the main activity.我为主要活动创建了一个 ViewModel。 Now I want to get an instance of the ViewModel in the main activity.现在我想在主活动中获取 ViewModel 的一个实例。

Most Tutorials and answers here on Stackoverflow suggest using ViewModelProviders.of(... , but this is depreceated. Stackoverflow 上的大多数教程和答案都建议使用ViewModelProviders.of(... ,但已弃用。

So according to this question on stackoverflow: ViewModelProviders is deprecated in 1.1.0 main activity in onCreate, I do the following (and I could swear I already had it running): mainActivityViewModel = new ViewModelProvider(this).get(MainActivityViewModel.class);因此,根据stackoverflow上的这个问题: ViewModelProviders is deprecated in 1.1.0 main activity in onCreate,我执行以下操作(我可以发誓我已经运行了它): mainActivityViewModel = new ViewModelProvider(this).get(MainActivityViewModel.class);

However, I am getting an error telling me, that no suitable constructor has been found.但是,我收到一个错误消息,告诉我没有找到合适的构造函数。

error: no suitable constructor found for ViewModelProvider(MainActivity)

Alternatively to make absolutely clear, that the MainActivity shall be the ViewModelStoreOwner, I created a variable ViewModelStoreOwner vmso = this;或者,为了明确说明,MainActivity 应该是 ViewModelStoreOwner,我创建了一个变量ViewModelStoreOwner vmso = this; and put that variable into the constructor like so: mainActivityViewModel = new ViewModelProvider(vmso).get(MainActivityViewModel.class);并将该变量放入构造函数中,如下所示: mainActivityViewModel = new ViewModelProvider(vmso).get(MainActivityViewModel.class);

You should update your gradle file to:您应该将 gradle 文件更新为:

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

And due to this change you can pass Activity to the constructor you mentioned:由于此更改,您可以将 Activity 传递给您提到的构造函数:

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

Using Fragment-ktx libr in your app you can get viewModel as below在您的应用程序中使用Fragment-ktx libr ,您可以获得如下所示的 viewModel

First Update Gradle File as app -> build.gradle首先将 Gradle 文件更新为 app -> build.gradle

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

// get ViewModel in Activity or Fragment as // 获取ActivityFragment 中的ViewModel as

private val viewModel: MainActivityViewModel by viewModels()

// If you want to get same instance of ViewModel in ChildFragment as // 如果你想在ChildFragment 中获得相同的ViewModel实例

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

Use val viewModel by viewModels<TheViewModel>() in Activities and val viewModel by activityViewModels<TheViewModel>() in fragment to obtain the same viewmodel from the activity (so sharing the viewmodel).在活动中val viewModel by viewModels<TheViewModel>()使用val viewModel by viewModels<TheViewModel>()在片段中val viewModel by activityViewModels<TheViewModel>()使用val viewModel by viewModels<TheViewModel>()从活动中获取相同的视图模型(因此共享视图模型)。

This is part of androidx now这是现在androidx一部分

For now, the only thing working for me was to use: MainActivityViewModel = new ViewModelProvider(this, new ViewModelProvider.NewInstanceFactory()).get(MainActivityViewModel.class);目前,唯一对我有用的是使用: MainActivityViewModel = new ViewModelProvider(this, new ViewModelProvider.NewInstanceFactory()).get(MainActivityViewModel.class);

However, I am still thankful for any advice, how this can be done different using new ViewModelProvider(this).get(MainActivityViewModel.class);但是,我仍然感谢任何建议,如何使用new ViewModelProvider(this).get(MainActivityViewModel.class);

Get ViewModel In New Way以新方式获取 ViewModel

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

Duplicate question and already answered here 重复的问题,已经在这里回答

Simply replace:简单替换:

This:这个:

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

With this:有了这个:

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

You can use a ViewModelFactory :您可以使用ViewModelFactory

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

VMFactory code:虚拟机工厂代码:

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
    }
}

Please note that here my MainViewModel extends AndroidViewModel and hence requires application as the input parameter.请注意,这里我的MainViewModel扩展了AndroidViewModel ,因此需要 application 作为输入参数。

I had similar problems and in the end found out I missed off the " extends ViewModel " within the class definition, so it should look like this:我遇到了类似的问题,最后发现我错过了类定义中的“ 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;
}

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

Android Support library version is depreciated. Android 支持库版本已折旧。 So you need to make sure that you import Androidx.所以你需要确保你导入了Androidx。 And you need to implement androidx dependency in Gradle file.并且您需要在 Gradle 文件中实现 androidx 依赖项。

It is not advised to create a new ViewModel object with "new" keyword.不建议使用“new”关键字创建新的 ViewModel 对象。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM