【发布时间】:2019-12-23 08:58:51
【问题描述】:
我一直在尝试在 Activity 中创建 ViewModel 的对象,但不推荐使用 ViewModelProviders 那么创建 ViewModel 对象的替代方法是什么。
【问题讨论】:
我一直在尝试在 Activity 中创建 ViewModel 的对象,但不推荐使用 ViewModelProviders 那么创建 ViewModel 对象的替代方法是什么。
【问题讨论】:
接下来几个月的简单选择是坚持使用稳定版或测试版。 ViewModelProviders 仅从 2.2.0 开始被弃用,目前在 alpha03 版本中。
当您确实迁移到 2.2.0 或更高版本的生命周期依赖项时,您的选择取决于您的语言:
如果您使用 Java,请使用 ViewModelProvider() 构造函数,传入您的活动或片段
如果你使用 Kotlin,应该有一个 by viewModels() 属性委托,虽然我在源代码中没有找到它...
【讨论】:
by viewModels()你需要添加这个依赖implementation 'androidx.fragment:fragment-ktx:1.2.0'
by viewModels() 和by activityViewModels() 是在fragment-ktx 和activity-ktx 工件中定义的。
ViewModelProviders.of() 已被弃用。您可以将 Fragment 或 FragmentActivity 传递给新的 ViewModelProvider(ViewModelStoreOwner) 构造函数以实现相同的功能。 (aosp/1009889)
【讨论】:
如果您使用的是 Kotlin,而不是:
private lateinit var viewModel: EntityGridViewModel
[...]
// Deprecated
viewModel = ViewModelProviders.of(this).get(EntityGridViewModel::class.java)
你可以使用更好的:
private val viewModel: EntityGridViewModel by viewModels()
【讨论】:
简单替换:
这个:
boardViewModel = ViewModelProviders.of(this).get(BoardViewModel::class.java)
有了这个:
boardViewModel = ViewModelProvider(this).get(BoardViewModel::class.java)
【讨论】:
【讨论】:
this 更改为getViewLifecycleOwner() 以避免警告。
这次 Gradle 升级给我带来了问题。
来自
implementation 'androidx.core:core:1.1.0'
到
implementation 'androidx.core:core:1.2.0'
在主要活动 Java/Kotlin 文件中
这个导入语句
import androidx.lifecycle.ViewModelProviders
不得不改成
import androidx.lifecycle.ViewModelProvider
这个 KOTLIN viewModel 语句
viewModel = ViewModelProviders.of(this).get(MainActivityViewModel::class.java)
不得不改成
viewModel = ViewModelProvider(this).get(MainActivityViewModel::class.java)
在 JAVA 中
这行JAVA代码
mViewModel = ViewModelProviders.of(this).get(MainActivityViewModel.class);
不得不改成
mViewModel = new ViewModelProvider(this).get(MainActivityViewModel.class);
然后这一切都对我有用。
【讨论】:
此类已弃用。 直接使用 ViewModelProvider 的构造函数。 here
所以不要使用这个
ViewModelProviders.of(this).get(MyViewModel.class); - deprecated
使用这个
new ViewModelProvider(this).get(MyViewModel.class); - correct
【讨论】:
我们现在应该使用 ViewModelProvider 构造函数,而不是 ViewModelProviders,它有三个:
public ViewModelProvider(ViewModelStoreOwner owner)
public ViewModelProvider(ViewModelStoreOwner owner, Factory factory)
public ViewModelProvider(ViewModelStore store, Factory factory)
1. 如果您没有使用ViewModelProvider.Factory 到pass additional arguments 到您的ViewModel,您可以使用第一个。所以:
viewModel = ViewModelProviders.of(this).get(YourViewModel.class);
可以替换为:
viewModel = new ViewModelProvider(this).get(YourViewModel.class);
AppCompatActivity 和不同类型的Fragments 是ViewModelStoreOwner 的间接子类(请参阅其已知子类here 的完整列表),因此您可以在此构造函数中使用它们。
2.但是如果你使用ViewModelProvider.Factory,你应该使用第二个或第三个构造函数:
viewModel = ViewModelProviders.of(this, viewModelFactory).get(YourViewModel.class);
可以替换为:
viewModel = new ViewModelProvider(this, viewModelFactory).get(YouViewModel.class);
或基于documentation 的ViewModelStore:
使用 ViewModelStoreOwner.getViewModelStore() 检索一个 Activity 和 Fragment 的 ViewModelStore。
viewModel = new ViewModelProvider(getViewModelStore(), viewModelFactory).get(YourViewModel.class);
【讨论】:
由于 ViewModelProviders 已被弃用。您现在可以直接使用 ViewModelProvider 构造函数。更多使用方法请查看here。
【讨论】:
此代码适用于我
private lateinit var viewModel: MainViewModel
viewModel = ViewModelProvider(this, ViewModelProvider.NewInstanceFactory()).get(MainViewModel::class.java)
【讨论】:
您可以在应用程序build.gradle中添加以下依赖项:
//for activity
implementation "androidx.activity:activity-ktx:1.2.2"
//for fragment
implementation "androidx.fragment:fragment-ktx:1.3.2"
然后像下面这样使用:
private val viewmodel: YOUR_VIEW_MODEL_CLASS_NAME by viewModels()
如果你有自己的视图模型工厂,那么
private val viewmodel: YOUR_VIEW_MODEL_CLASS_NAME by viewModels { YOUR_VIEW_MODEL_FACTORY }
【讨论】:
对于java:
简单地替换这个:
viewModel = ViewModelProviders.of(this).get(YOUR_VIEW_MODEL::class.java)
有了这个:
viewModel = ViewModelProvider(this).get(YOUR_VIEW_MODEL::class.java)
如果你有自己的工厂,那么
viewModel =
ViewModelProvider(this,YOUR_FACTORY).get(YOUR_VIEW_MODEL::class.java)
对于kotlin:
有一种更好的方法可以做到这一点。您可以在应用程序build.gradle 中添加以下依赖项:
//for activity
implementation "androidx.activity:activity-ktx:1.3.0-alpha06"
//for fragment
implementation "androidx.fragment:fragment-ktx:1.3.2"
然后像下面这样访问视图模型:
private val viewmodel: YOUR_VIEW_MODEL by viewModels()
如果你有自己的视图模型工厂,那么
private val viewmodel: YOUR_VIEW_MODEL by viewModels { YOUR_VIEW_MODEL_FACTORY }
【讨论】: