Sea*_*ici 10 android viewmodel kotlin android-architecture-navigation android-navigation-graph
我正在使用 Android Jetpack (2.2.0-alpha01) 的导航组件。
我希望使用嵌套在我的主 NavHostFragment 中的子 NavHostFragment,它配备了自己的子导航图。请查看以下图片了解上下文:
子导航主机在位于 MainNavHost 堆栈前端的片段中定义如下:
<fragment
android:id="@+id/childNavHostFragment"
android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:defaultNavHost="false"
app:navGraph="@navigation/child_graph" />
Run Code Online (Sandbox Code Playgroud)
在 CHILD Nav Host Fragment 前面的片段中,我尝试使用以下代码将 ViewModel 范围限定为 R.navigation.child_graph:
private val childGraphScopedViewModel: ChildGraphScopedViewModel by navGraphViewModels(R.navigation.child_graph) {
viewModelFactory
}
Run Code Online (Sandbox Code Playgroud)
访问 childGraphScopedViewModel 时,我收到错误消息崩溃:
java.lang.IllegalArgumentException: No NavGraph with ID 2131689472 is on the NavController's back stack.
Run Code Online (Sandbox Code Playgroud)
我相信懒惰的 init 调用by navGraphViewModel()是在 mainGraph 中寻找导航图。
如何访问子 navHostFragment 范围的 ViewModel?感谢您的时间。
这对我有用,无需定义自定义ViewModelProvider(2.2.0):
private val viewModel: ChildGraphScopedViewModel by navGraphViewModels(R.id. child_graph)
一个容易犯的错误是使用R.navigation.child_graph(坏)而不是R.id.child_graph(好)
您可以通过提供 child 的 viewModelStore 来做到这一点NavController
override fun onViewCreated(
view: View,
savedInstanceState: Bundle?
) {
super.onViewCreated(view, savedInstanceState)
val childHostFragment = childFragmentManager
.findFragmentById(R.id.childNavHostFragment) as NavHostFragment
val childNavController = childHostFragment.navController
val childViewModel: ChildGraphScopedViewModel = ViewModelProvider(
childNavController.getViewModelStoreOwner(R.navigation.child_graph)
).get(ChildGraphScopedViewModel::class.java)
}
Run Code Online (Sandbox Code Playgroud)
我编写了一个 Kotlin 扩展以使其更容易
inline fun <reified T: ViewModel> NavController.viewModel(@NavigationRes navGraphId: Int): T {
val storeOwner = getViewModelStoreOwner(navGraphId)
return ViewModelProvider(storeOwner)[T::class.java]
}
Run Code Online (Sandbox Code Playgroud)
用法
val viewModel = findNavController().viewModel(R.navigation.nav)
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
4716 次 |
| 最近记录: |