查看ViewModel的谷歌文档,他们展示了下面如何获取ViewModel的示例代码:
val model = ViewModelProviders.of(this).get(MyViewModel::class.java)
当使用最新的依赖项android.arch.lifecycle:extensions:1.1.1时,没有这样的类ViewModelProviders。
去查看ViewModelProviders的文档,我看到一条评论说:
这个类在API级别1.1.0中已弃用。使用ViewModelProvider。AndroidViewModelFactory
问题是,当尝试使用ViewModelProvider时。AndroidViewModelFactory,找不到一个等效的方法来获取ViewModel的实例。
我尝试做的事情:
ViewModelProvider.AndroidViewModelFactory.getInstance(application).create(PlayerViewHolder::class.java)
因此,方法的名称创建,我得到一个新的实例的ViewModel每次我调用它,这不是我所追求的。
有什么想法是替换上面已弃用的代码?
实际上,ViewModelProviders.of()方法在底层做什么?
@Deprecated
@NonNull
@MainThread
public static ViewModelProvider of(@NonNull Fragment fragment) {
return new ViewModelProvider(fragment);
}
它以Fragment作为参数,创建ViewModelProvider对象,并将片段直接传递给ViewModelProvider构造函数。
我们也可以用同样的方法。
例如:
OurViewModel mOurViewModel = ViewModelProviders.of(this).get(OurViewModel.class);
后:
OurViewModel mOurViewModel = new ViewModelProvider(this).get(OurViewModel.class);
//Activity ktx
implementation 'androidx.activity:activity-ktx:1.5.1'
//Fragment ktx
implementation 'androidx.fragment:fragment-ktx:1.5.1'
创建视图模型的最简单方法:
class MyViewModel() : ViewModel() {
}
class SomeActivity:AppCompatActivity(){
private val viewModel: MyViewModel by viewModels()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_some)
}
}
带有构造函数参数的视图模型:
class MyViewModel(list:List<String>) : ViewModel() {
class Factory(list:List<String>) : ViewModelProvider.Factory {
@Suppress("unchecked_cast")
override fun <T : ViewModel> create(modelClass: Class<T>): T {
return MyViewModel(list) as T
}
}
}
class SomeActivity:AppCompatActivity(){
private val viewModel: MyViewModel by viewModels(){
MyViewModel.Factory(listOf<String>("a"))}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
}
}
早在2020年,谷歌已经在androidx生命周期库2.2.0版本中弃用了ViewModelProviders类。
不再需要使用ViewModelProviders来创建ViewModel的实例,您可以将您的Fragment或Activity实例传递给ViewModelProvider构造函数。
如果你使用如下代码:
val viewModel = ViewModelProviders.of(this).get(CalculatorViewModel::class.java)
你会得到一个警告,ViewModelProviders已被弃用。
要避免使用已弃用的库,请进行以下更改:
In the build.gradle (Module: app) file, use version 2.2.0 of the lifecycle
components:
implementation 'androidx.lifecycle:lifecycle-extensions:2.2.0'
implementation "androidx.activity:activity-ktx:1.1.0"
If you want to use the ViewModel from a Fragment instead, use
implementation "androidx.fragment:fragment-ktx:1.2.2"
fragment-ktx automatically includes activity-ktx, so you don't need to
specify both in the dependencies.
You need to specify Java 8 in the android section :
android {
compileSdkVersion 28
defaultConfig {
applicationId "com.kgandroid.calculator"
minSdkVersion 17
targetSdkVersion 28
versionCode 1
versionName "1.0"
testInstrumentationRunner
"androidx.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'),
'proguard-rules.pro'
}
}
kotlinOptions { jvmTarget = "1.8" }
}
In your Fragment or Activity, change the import to:
import androidx.activity.viewModels
The code to create a ViewModel then becomes:
val viewModel: CalculatorViewModel by viewModels()
instead of
val viewModel = ViewModelProviders.of(this).get(CalculatorViewModel::class.java)
Use the viewModel object as :
val viewModel: CalculatorViewModel by viewModels()
viewModel.newNumber.observe(this, Observer<String> {
stringResult -> newNumber.setText(stringResult)
})
where newNumer is a LiveData object
In a Fragment that you want to share the Activity's ViewModel, you'd use
val viewModel: CalculatorViewModel by activityViewModels()
这相当于在(已弃用的)ViewModelProviders.of()函数中传递Activity实例。
我正在使用生命周期库2.3.1,并在构建中添加以下依赖项。gradle(模块级)
implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.3.1'
implementation 'androidx.lifecycle:lifecycle-livedata-ktx:2.3.1'
implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.3.1'
implementation 'androidx.lifecycle:lifecycle-extensions-ktx:2.2.0'
implementation 'androidx.activity:activity-ktx:1.4.0'
implementation 'androidx.fragment:fragment-ktx:1.3.6'
在你的Kotlin代码中声明viewModels(),如下所示:
import androidx.fragment.app.viewModels
private val cartViewModel: CartViewModel by viewModels()