Compose 中的底部导航
Bottom Navigation in Compose
我想用两个项目创建 BottomNavigation
。每个项目的屏幕都是在 Compose 中构建的。
我的 LeadActivity
布局:
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent">
<androidx.fragment.app.FragmentContainerView
android:id="@+id/nav_host_fragment"
android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:defaultNavHost="true"
app:navGraph="@navigation/nav_graph"
tools:ignore="FragmentTagUsage" />
</FrameLayout>
导航图:
<navigation xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/nav_graph"
app:startDestination="@+id/home_fragment">
<fragment
android:id="@+id/home_fragment"
android:name="com.app.android.rate.home.ui.Home.HomeFragment"
android:label="Home" />
<fragment
android:id="@+id/profile_fragment"
android:name="com.app.android.rate.home.ui.profile.ProfileFragment"
android:label="Profile"></fragment>
</navigation>
LeadActivity:
class LeadActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
RateMeAppTheme {
ContentScreen()
}
}
}
companion object {
fun start(context: Context) =
Intent(context, LeadActivity::class.java).let(context::startActivity)
}
}
我的可组合函数:
@Composable
fun ContentScreen() {
val navController = rememberNavController()
val scaffoldState = rememberScaffoldState()
var currentScreen by remember { mutableStateOf(Screens.Home) }
val bottomBar: @Composable () -> Unit = {
if (currentScreen == Screens.Home) {
BottomBar(
navController = navController,
screens = screenList
)
}
}
Scaffold(
bottomBar = {
bottomBar()
},
scaffoldState = scaffoldState,
drawerContent = {},
drawerGesturesEnabled = scaffoldState.drawerState.isOpen,
) { innerPadding ->
NavigationHost(navController = navController)
}
}
@Composable
fun BottomBar(
modifier: Modifier = Modifier,
screens: List<Screens>,
navController: NavController,
) {
BottomNavigation(modifier = modifier) {
val navBackStackEntry by navController.currentBackStackEntryAsState()
val currentRoute = navBackStackEntry?.arguments?.getString(KEY_ROUTE)
screens.forEach { screen ->
BottomNavigationItem(
icon = { Icon(imageVector = screen.icon, contentDescription = screen.title) },
label = { Text(screen.title) },
selected = currentRoute == screen.title,
onClick = {
}
)
}
}
}
@Composable
fun NavigationHost(navController: NavController) {
val homeScreen = Screens.Home.title
NavHost(
navController = navController as NavHostController,
startDestination = homeScreen
) {
composable(homeScreen) {
navController.navigate(R.id.home_fragment)
}
composable(Screens.Profile.title) {
navController.navigate(R.id.profile_fragment)
}
}
}
目前我得到错误:
导航action/destinationcom.app.android.rate:id/home_fragment无法从当前目的地Destination找到。
我是否应该在 LeadActivity
中找到 NavController
并将其传递给 @ContentScreen()
?
你没有把 navController.navigate()
放在 composable
函数里面,你放了一个 Composable
视图
我想用两个项目创建 BottomNavigation
。每个项目的屏幕都是在 Compose 中构建的。
我的 LeadActivity
布局:
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent">
<androidx.fragment.app.FragmentContainerView
android:id="@+id/nav_host_fragment"
android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:defaultNavHost="true"
app:navGraph="@navigation/nav_graph"
tools:ignore="FragmentTagUsage" />
</FrameLayout>
导航图:
<navigation xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/nav_graph"
app:startDestination="@+id/home_fragment">
<fragment
android:id="@+id/home_fragment"
android:name="com.app.android.rate.home.ui.Home.HomeFragment"
android:label="Home" />
<fragment
android:id="@+id/profile_fragment"
android:name="com.app.android.rate.home.ui.profile.ProfileFragment"
android:label="Profile"></fragment>
</navigation>
LeadActivity:
class LeadActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
RateMeAppTheme {
ContentScreen()
}
}
}
companion object {
fun start(context: Context) =
Intent(context, LeadActivity::class.java).let(context::startActivity)
}
}
我的可组合函数:
@Composable
fun ContentScreen() {
val navController = rememberNavController()
val scaffoldState = rememberScaffoldState()
var currentScreen by remember { mutableStateOf(Screens.Home) }
val bottomBar: @Composable () -> Unit = {
if (currentScreen == Screens.Home) {
BottomBar(
navController = navController,
screens = screenList
)
}
}
Scaffold(
bottomBar = {
bottomBar()
},
scaffoldState = scaffoldState,
drawerContent = {},
drawerGesturesEnabled = scaffoldState.drawerState.isOpen,
) { innerPadding ->
NavigationHost(navController = navController)
}
}
@Composable
fun BottomBar(
modifier: Modifier = Modifier,
screens: List<Screens>,
navController: NavController,
) {
BottomNavigation(modifier = modifier) {
val navBackStackEntry by navController.currentBackStackEntryAsState()
val currentRoute = navBackStackEntry?.arguments?.getString(KEY_ROUTE)
screens.forEach { screen ->
BottomNavigationItem(
icon = { Icon(imageVector = screen.icon, contentDescription = screen.title) },
label = { Text(screen.title) },
selected = currentRoute == screen.title,
onClick = {
}
)
}
}
}
@Composable
fun NavigationHost(navController: NavController) {
val homeScreen = Screens.Home.title
NavHost(
navController = navController as NavHostController,
startDestination = homeScreen
) {
composable(homeScreen) {
navController.navigate(R.id.home_fragment)
}
composable(Screens.Profile.title) {
navController.navigate(R.id.profile_fragment)
}
}
}
目前我得到错误:
导航action/destinationcom.app.android.rate:id/home_fragment无法从当前目的地Destination找到。
我是否应该在 LeadActivity
中找到 NavController
并将其传递给 @ContentScreen()
?
你没有把 navController.navigate()
放在 composable
函数里面,你放了一个 Composable
视图