【发布时间】:2022-02-12 18:14:39
【问题描述】:
我在一个正在慢慢采用 Jetpack Compose 的项目中工作。它主要是一个Activity 多个Fragments 应用程序,我们使用Android 的导航组件来处理到每个屏幕的转换(Fragment)。只要有可能,我们只会用 Composables 替换 Fragments 的 XML 布局。
到目前为止,案件的处理方式如下:
A. Fragments 显示可组合并处理导航:
class ScreenFragment : Fragment() {
// For observing events that trigger navigation
private val viewModel by lazyViewModel { ScreenViewModel() }
override fun onCreateView( ... ): View {
return ComposeView(requireContext()).apply {
setViewCompositionStrategy(DisposeOnLifecycleDestroyed(viewLifecycleOwner))
setContent {
AppTheme {
Screen(onBackPressed = { findNavController().navigateUp() })
}
}
}
}
...
}
B.可组合处理与 UI 相关的所有其他内容:
@Composable
fun CreatePassword(
onBackPressed: () -> Unit,
) {
// For observing UI states and events
val viewModel: CreatePasswordViewModel = viewModel()
...
}
如您所见,我们的 Fragments 和 Composables 中都有屏幕 ViewModel 的引用。到目前为止,这一直运行良好,可组合的 viewModel() 函数始终返回 Fragment 的 ViewModel 的相同现有实例。
当我们需要将 ViewModel 的引用范围限定为可组合对象上的 Activity 时,问题就出现了:
- 我们在
Activity上创建ViewModel:
class MainActivity : AppCompatActivity() {
private val viewModel by lazyViewModel { MainViewModel() }
...
}
- 在
Fragment上为MainActivity的ViewModel提供参考,点赞
class MainFragment : Fragment() {
private val viewModel: MainViewModel by viewModels(::requireActivity)
...
}
- 我们得到了可组合组件的 ViewModel 参考,如上所示(项目 B)
通过这样做,Fragment 具有相同的 Activity 实例,但可组合对象没有。
我的问题是,
是否可以在可组合物中获取Activity 的ViewModel 的引用? 现在我只是将Fragment 的ViewModel 作为参数传递给我的主要可组合屏幕。
【问题讨论】:
-
viewModel()将ViewModelStoreOwner作为参数来控制该 ViewModel 的范围,就像您的lazyViewModel一样。如果您想将 ViewModel 限定为您的 Activity,为什么不将您的 Activity 传递给viewModel()? -
为什么不将视图模型作为参数传递给 CreatePassword 组合?
-
@ianhanniballake,我尝试将我的
Activity传递给viewModel(),但我最终也得到了一个新的viewModel 实例。我得到了我的Activity,如下所示:stackoverflow.com/a/68423182/8189765 -
@MobinYardim 这正是我现在正在做的事情。
标签: android android-jetpack-compose android-viewmodel