如何使用 ViewModel 的新保存状态模块
How do I use the new Saved State Module of ViewModel
我使用的是生命周期版本 2.2.0-rc03 和 official docs,发现的文章甚至没有列出正确的 class 名称或构造函数参数。我想我必须通过这样的方式获取 ViewModel 实例
viewModel = ViewModelProvider(this, SavedStateViewModelFactory(requireActivity().application, savedStateRegistryOwner))
.get(SelectedTracksViewModel::class.java)
但我不知道 SavedStateRegistryOwner。
有人可以举一个简单的例子来说明如何创建保存状态的 ViewModel 实例以及在 ViewModel 中保存和恢复值的正确方法吗?
据我了解,您想使用规范构造函数创建视图模型。
您可以使用 ViewModelProvider.Factory
.
viewModel = ViewModelProvider(this, SavedStateViewModelFactory.create(state)
.get(SelectedTracksViewModel::class.java)
ViewModelFactory 示例
public class SavedStateViewModelFactory {
public static <E> ViewModelProvider.Factory create(State state){
return new ViewModelProvider.Factory() {
@NonNull
@Override
@SuppressWarnings("unchecked")
public <T extends ViewModel> T create(@NonNull Class<T> modelClass) {
if (modelClass.isAssignableFrom(SelectedTracksViewModel.class)) {
return (T) new SelectedTracksViewModel<>(state);
} else {
throw new IllegalArgumentException("Unknown ViewModel class");
}
}
};
}
}
要为视图模型使用保存状态模块,您必须将 androidx.lifecycle:lifecycle-viewmodel-savedstate
依赖项添加到项目中。本例基于1.0.0-rc03
.
版本编写
请将以下行添加到您的项目 Gradle 文件中:
implementation 'androidx.lifecycle:lifecycle-viewmodel-savedstate:1.0.0-rc03'
视图模型实现:
class SavedStateViewModel(private val state: SavedStateHandle) : ViewModel() {
val liveData = state.getLiveData("liveData", Random.nextInt().toString())
fun saveState() {
state.set("liveData", liveData.value)
}
}
Activity 实施:
class SavedStateActivity : AppCompatActivity() {
lateinit var viewModel: SavedStateViewModel;
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val binding: ActivityStateBinding = DataBindingUtil.setContentView(this, R.layout.activity_state)
viewModel = ViewModelProvider(this, SavedStateViewModelFactory(this.application, this)).get(SavedStateViewModel::class.java)
binding.viewModel = viewModel
binding.lifecycleOwner = this
}
override fun onSaveInstanceState(outState: Bundle) {
if(::viewModel.isInitialized)
viewModel.saveState()
super.onSaveInstanceState(outState)
}
}
我已经测试了这段代码,它工作正常。
我正在为这个旧 post 添加一个答案,以防万一有人觉得它有用。
我设法做到了,如下所示:
- 将以下依赖项添加到您的“build.gradle(模块:app)”文件
implementation 'androidx.lifecycle:lifecycle-extensions:2.2.0'
- 将
savedState: SavedStateHandle
属性添加到ViewModel
的构造函数中
class SelectedTracksViewModel(private val savedState: SavedStateHandle) : ViewModel() {
companion object {
private const val SAVED_TRACK_INDEX = "savedTrackIndex"
}
private var trackIndex: Int
set(value) {
field = value
// Simply update the savedState every time your saved property changes
savedState.set(SAVED_TRACK_INDEX, value)
}
init {
trackIndex = savedState.get<Int>(SAVED_TRACK_INDEX) ?: 0
}
fun moveToNextTrack() {
trackIndex++
// Initially I was updating savedState here - now moved to setter
// Some more code here
}
}
终于在activity/fragment
private val selectedTracksViewModel: SelectedTracksViewModel by lazy {
ViewModelProvider(this).get(SelectedTracksViewModel::class.java)
}
就是这样。不需要 SavedStateViewModelFactory
,只需将 savedState
属性 添加到您的 ViewModel
构造函数并在跟踪属性更改时更新它。其他一切都像你没有使用 savedState: SavedStateHandle
一样工作,这种方式与 activities/fragments.
中的传统 onSaveInstanceState(Bundle)
非常相似
更新: 最初我是在更改 trackIndex
后更新 savedState
。这意味着每次 保存的属性更改时都必须更新 savedState
。如果忘记添加该行,这将是一个巨大的潜在未来错误。一个更好更健壮的模式是更新 属性.
的 setter 中的 savedState
我使用的是生命周期版本 2.2.0-rc03 和 official docs,发现的文章甚至没有列出正确的 class 名称或构造函数参数。我想我必须通过这样的方式获取 ViewModel 实例
viewModel = ViewModelProvider(this, SavedStateViewModelFactory(requireActivity().application, savedStateRegistryOwner))
.get(SelectedTracksViewModel::class.java)
但我不知道 SavedStateRegistryOwner。
有人可以举一个简单的例子来说明如何创建保存状态的 ViewModel 实例以及在 ViewModel 中保存和恢复值的正确方法吗?
据我了解,您想使用规范构造函数创建视图模型。
您可以使用 ViewModelProvider.Factory
.
viewModel = ViewModelProvider(this, SavedStateViewModelFactory.create(state)
.get(SelectedTracksViewModel::class.java)
ViewModelFactory 示例
public class SavedStateViewModelFactory {
public static <E> ViewModelProvider.Factory create(State state){
return new ViewModelProvider.Factory() {
@NonNull
@Override
@SuppressWarnings("unchecked")
public <T extends ViewModel> T create(@NonNull Class<T> modelClass) {
if (modelClass.isAssignableFrom(SelectedTracksViewModel.class)) {
return (T) new SelectedTracksViewModel<>(state);
} else {
throw new IllegalArgumentException("Unknown ViewModel class");
}
}
};
}
}
要为视图模型使用保存状态模块,您必须将 androidx.lifecycle:lifecycle-viewmodel-savedstate
依赖项添加到项目中。本例基于1.0.0-rc03
.
请将以下行添加到您的项目 Gradle 文件中:
implementation 'androidx.lifecycle:lifecycle-viewmodel-savedstate:1.0.0-rc03'
视图模型实现:
class SavedStateViewModel(private val state: SavedStateHandle) : ViewModel() {
val liveData = state.getLiveData("liveData", Random.nextInt().toString())
fun saveState() {
state.set("liveData", liveData.value)
}
}
Activity 实施:
class SavedStateActivity : AppCompatActivity() {
lateinit var viewModel: SavedStateViewModel;
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val binding: ActivityStateBinding = DataBindingUtil.setContentView(this, R.layout.activity_state)
viewModel = ViewModelProvider(this, SavedStateViewModelFactory(this.application, this)).get(SavedStateViewModel::class.java)
binding.viewModel = viewModel
binding.lifecycleOwner = this
}
override fun onSaveInstanceState(outState: Bundle) {
if(::viewModel.isInitialized)
viewModel.saveState()
super.onSaveInstanceState(outState)
}
}
我已经测试了这段代码,它工作正常。
我正在为这个旧 post 添加一个答案,以防万一有人觉得它有用。
我设法做到了,如下所示:
- 将以下依赖项添加到您的“build.gradle(模块:app)”文件
implementation 'androidx.lifecycle:lifecycle-extensions:2.2.0'
- 将
savedState: SavedStateHandle
属性添加到ViewModel
的构造函数中
class SelectedTracksViewModel(private val savedState: SavedStateHandle) : ViewModel() {
companion object {
private const val SAVED_TRACK_INDEX = "savedTrackIndex"
}
private var trackIndex: Int
set(value) {
field = value
// Simply update the savedState every time your saved property changes
savedState.set(SAVED_TRACK_INDEX, value)
}
init {
trackIndex = savedState.get<Int>(SAVED_TRACK_INDEX) ?: 0
}
fun moveToNextTrack() {
trackIndex++
// Initially I was updating savedState here - now moved to setter
// Some more code here
}
}
终于在activity/fragment
private val selectedTracksViewModel: SelectedTracksViewModel by lazy {
ViewModelProvider(this).get(SelectedTracksViewModel::class.java)
}
就是这样。不需要 SavedStateViewModelFactory
,只需将 savedState
属性 添加到您的 ViewModel
构造函数并在跟踪属性更改时更新它。其他一切都像你没有使用 savedState: SavedStateHandle
一样工作,这种方式与 activities/fragments.
onSaveInstanceState(Bundle)
非常相似
更新: 最初我是在更改 trackIndex
后更新 savedState
。这意味着每次 保存的属性更改时都必须更新 savedState
。如果忘记添加该行,这将是一个巨大的潜在未来错误。一个更好更健壮的模式是更新 属性.
savedState