use*_*123 1 android viewmodel kotlin dagger dagger-hilt
我正在使用ViewModel更新操作栏中的标题
共享视图模型
class SharedViewModel @ViewModelInject constructor(
@Assisted private val savedStateHandle: SavedStateHandle
) : ViewModel() {
val title: MutableLiveData<String> by lazy {
MutableLiveData<String>()
}
val backButton: MutableLiveData<Boolean> by lazy {
MutableLiveData<Boolean>()
}
}
Run Code Online (Sandbox Code Playgroud)
主活动观察者
@AndroidEntryPoint
...
sharedViewModel.title.observe(this, Observer {
supportActionBar?.title = it
})
Run Code Online (Sandbox Code Playgroud)
使用下面的代码似乎创建了一个新实例Fragment(在调试器中检查):
@AndroidEntryPoint
...
private val viewModel: SharedViewModel by viewModels()
Run Code Online (Sandbox Code Playgroud)
但似乎以这种方式工作
val viewModel = ViewModelProvider(requireActivity()).get(SharedViewModel::class.java)
Run Code Online (Sandbox Code Playgroud)
这是应该这样做还是我做错了什么?
谢谢!
如果你想在一个片段使用共享视图模型,你必须使用by activityViewModels()替代by viewModels()。
为什么下一行有效但by viewModels()无效?
ViewModelProvider(requireActivity()).get(SharedViewModel::class.java)
Run Code Online (Sandbox Code Playgroud)
因为默认情况下viewModels()其ownerProducer参数值为{ this }. 为了更好地理解它,这里是源代码:
@MainThread
inline fun <reified VM : ViewModel> Fragment.viewModels(
noinline ownerProducer: () -> ViewModelStoreOwner = { this },
noinline factoryProducer: (() -> Factory)? = null
) = createViewModelLazy(VM::class, { ownerProducer().viewModelStore }, factoryProducer)
Run Code Online (Sandbox Code Playgroud)
如您所见,它是Fragment类的扩展函数。这意味着 ViewModelStoreOwner是片段。一旦片段从堆栈中移除,它存储在视图模型存储中的所有视图模型都消失了。
但是如果你使用by activityViewModels()你Activity作为视图模型商店所有者。请注意,默认情况下使用 ofrequireActivity().viewModelStore而不是ownerProducer().viewModelStorewhich Fragment。
@MainThread
inline fun <reified VM : ViewModel> Fragment.activityViewModels(
noinline factoryProducer: (() -> Factory)? = null
) = createViewModelLazy(VM::class, { requireActivity().viewModelStore },
factoryProducer ?: { requireActivity().defaultViewModelProviderFactory })
Run Code Online (Sandbox Code Playgroud)
最终,createViewModelLazy正在调用
ViewModelProvider(store, factory).get(viewModelClass.java)
Run Code Online (Sandbox Code Playgroud)
这相当于您使用手动创建视图模型
ViewModelProvider(requireActivity()).get(SharedViewModel::class.java)
Run Code Online (Sandbox Code Playgroud)
使用by activityViewModels():
@AndroidEntryPoint
...
private val viewModel: SharedViewModel by activityViewModels()
Run Code Online (Sandbox Code Playgroud)
注意:by activityViewModels()并且by viewModels()只是ViewModelProvider(...).get(...).
| 归档时间: |
|
| 查看次数: |
1744 次 |
| 最近记录: |