使用 Fragments 实现 Compose 底部导航

Implement Compose Bottom Navigation using Fragments

我按照compose documentation创建了这样一个密封的底部导航栏class

sealed class Screen(val route: String, val label: String, val icon: ImageVector) {
    object ScreenA: Screen("screenA", "ScreenA", Icons.Default.AccountBox)
    object ScreenB: Screen("screenB", "ScreenB", Icons.Default.ThumbUp
}

例如下面的屏幕,只包含一个文本项。

@Composable
fun ScreenA() {
    Text(text = "This is ScreenA",
        style = TextStyle(color = Color.Black, fontSize = 36.sp),
        textAlign = TextAlign.Center)
}

并且还完全按照文档中的方式实现了 Scaffold, BottomNavigation, and NavHost,并且一切正常。

假设我现在想要一个屏幕,其中有一大堆数据显示在一个列表中,其中包含各种业务逻辑方法,这需要 Fragment、ViewModel、Repository 等等。 正确的方法是什么?我仍然可以创建片段并以某种方式将它们传递给密封的 class 还是我们应该忘记片段并使所有内容都可组合?

由于您正在关注文档,因此您需要忘记 Fragments。文档表明,当可组合函数为 called/navigated 时,将实例化每个屏幕的视图模型。当可组合对象未被释放时,视图模型将存在。这也是由单一 activity 方法激发的。

@Inject  lateinit var factory : ViewModelProvider.Factory


@Composable
fun Profile(profileViewModel = viewModel(factory),
    userId: String,
    navigateToFriendProfile: (friendUserId: String) -> Unit) {
  
}

这可以在 compose 示例中看到 here


如果你想混合使用两者,你​​可以省略使用 navigation-compose,并滚动导航组件并使用 Fragment 并且只对片段使用可组合 UI.

@AndroidEntryPoint
class ProfileFragment: BaseFragment() {

    private val profileViewModel by viewModels<ProfileViewModel>(viewModelFactory)
    private val profileFragmentArgs by navArg<ProfileFragmentArgs>()

    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        return ComposeView(requireContext()).apply {
            setContent {
               Profile(profileViewModel = profileViewModel, id = profileFragmentArgs.id, navigateToFriendProfile = { findNavController().navigate(...)  })  
            }
        }
    }