使用 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(...) })
}
}
}
我按照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(...) })
}
}
}