Advertisement

Compose_16--导航2(底部导航栏)

阅读量:

一、前置条件:

如果想要实现底部导航栏,同样需要一下依赖:

复制代码
 dependencies {

    
     implementation "androidx.navigation:navigation-compose:2.4.0-beta02"
    
 }

二、认识脚手架Scaffold

第10章--了解建筑模板系统已弃用个人博客-博客

三、认识底部导航栏--BottomNavigation

复制代码
 @Composable

    
 fun BottomNavigation(
    
     modifier: Modifier = Modifier,  // 修饰符
    
     backgroundColor: Color = MaterialTheme.colors.primarySurface, // 背景颜色
    
     contentColor: Color = contentColorFor(backgroundColor),  // 内容颜色
    
     elevation: Dp = BottomNavigationDefaults.Elevation, // 阴影大小
    
     content: @Composable RowScope.() -> Unit  // 内容
    
 )

四、认识底部导航栏项--BottomNavigationItem

复制代码
 @Composable

    
 fun RowScope.BottomNavigationItem(
    
     selected: Boolean,  // 是否选中
    
     onClick: () -> Unit,  // 点击事件
    
     icon: @Composable () -> Unit, // 导航项的icon
    
     modifier: Modifier = Modifier, // 导航项的修饰符
    
     enabled: Boolean = true,  //  是否可用
    
     label: @Composable (() -> Unit)? = null, // 标签(可理解为导航标题)
    
     // 是否总是显示标签(设置为false时,仅选中时显示标签)
    
     alwaysShowLabel: Boolean = true, 
    
     // 交互资源(自定义交互样式和行为)
    
     interactionSource: MutableInteractionSource = remember { MutableInteractionSource() },
    
     // 选中时的内容颜色(icon和标签的颜色)
    
     selectedContentColor: Color = LocalContentColor.current, 
    
     // 未选中时内容的颜色(icon和标签的颜色)
    
     unselectedContentColor: Color = selectedContentColor.copy(alpha = ContentAlpha.medium)
    
 )

五、获取当前项和是否选中状态

1.提取当前项:借助JavaScript的navBackStateEntryAsState()方法调用currentBackStateEntryAsState()函数来提取当前的navBackStateEntry对象;随后依次操作该对象即可完成提取过程以获得目标值

确定选中状态:通过当前节点NavDestination的层次结构来识别选中状态。

六、路由

该路由同时用于将onClick lambda与navigate函数关联起来,并且在点击时实现跳转功能。借助saveState和restoreState标志变量,在底部导航切换期间,系统能够准确地保存当前状态并正确恢复返回堆栈。

七、写一个简单例子

1.定义一个密封类

2.将定义的项放到BottomNavigationItem可使用的列表中

3.写底部导航栏

复制代码
 import androidx.annotation.StringRes

    
 import androidx.compose.foundation.layout.Box
    
 import androidx.compose.foundation.layout.fillMaxSize
    
 import androidx.compose.foundation.layout.padding
    
 import androidx.compose.material.*
    
 import androidx.compose.material.icons.Icons
    
 import androidx.compose.material.icons.outlined.AccountCircle
    
 import androidx.compose.material.icons.outlined.Home
    
 import androidx.compose.runtime.Composable
    
 import androidx.compose.runtime.getValue
    
 import androidx.compose.ui.Alignment
    
 import androidx.compose.ui.Modifier
    
 import androidx.compose.ui.graphics.Color
    
 import androidx.compose.ui.graphics.vector.ImageVector
    
 import androidx.compose.ui.res.stringResource
    
 import androidx.navigation.NavController
    
 import androidx.navigation.NavDestination.Companion.hierarchy
    
 import androidx.navigation.NavGraph.Companion.findStartDestination
    
 import androidx.navigation.compose.NavHost
    
 import androidx.navigation.compose.composable
    
 import androidx.navigation.compose.currentBackStackEntryAsState
    
 import androidx.navigation.compose.rememberNavController
    
 import android.os.Bundle
    
 import androidx.activity.ComponentActivity
    
 import androidx.activity.compose.setContent
    
  
    
 /** * 定义密封类
    
  */
    
 sealed class Screen(val route: String, @StringRes val resourceId: Int, val icon: ImageVector,) {
    
     object Home : Screen("home", R.string.home, Icons.Outlined.Home)
    
     object Profile : Screen("profile", R.string.profile, Icons.Outlined.AccountCircle)
    
 }
    
  
    
 /** * 将定义的项放到BottomNavigationItem可使用的列表中
    
  */
    
 val items = listOf(
    
     Screen.Home,
    
     Screen.Profile,
    
 )
    
  
    
 /** * 底部导航栏
    
  */
    
 @Composable
    
 fun compose_16() {
    
     val navController = rememberNavController()
    
     Scaffold(
    
     bottomBar = {
    
         BottomNavigation( backgroundColor = Color.White,) {
    
             val navBackStackEntry by navController.currentBackStackEntryAsState()
    
             val currentDestination = navBackStackEntry?.destination
    
             items.forEach { screen ->
    
                 BottomNavigationItem(
    
                     icon = { Icon(imageVector = screen.icon,
    
                         contentDescription = null) },
    
                     label = { Text(text = stringResource(screen.resourceId)) },
    
                     selected = currentDestination?.hierarchy?.any { it.route == screen.route } == true,
    
                     selectedContentColor = Color.Red,
    
                     unselectedContentColor = Color.Gray,
    
                     onClick = {
    
                         navController.navigate(screen.route) {
    
                             // Pop up to the start destination of the graph to
    
                             // avoid building up a large stack of destinations
    
                             // on the back stack as users select items
    
                             popUpTo(navController.graph.findStartDestination().id) {
    
                                 saveState = false
    
                             }
    
                             // Avoid multiple copies of the same destination when
    
                             // reselecting the same item
    
                             launchSingleTop = true
    
                             // Restore state when reselecting a previously selected item
    
                             restoreState = false
    
                         }
    
                     }
    
                 )
    
             }
    
         }
    
     }
    
     ) { innerPadding ->
    
     NavHost(navController, startDestination = Screen.Home.route, Modifier.padding(innerPadding)) {
    
         composable(Screen.Home.route) { Home_16(navController) }
    
         composable(Screen.Profile.route) { Mine(navController) }
    
     }
    
     }
    
 }
    
  
    
 @Composable
    
 fun Home_16(navController: NavController) {
    
     Box(modifier = Modifier.fillMaxSize(),
    
     contentAlignment = Alignment.Center) {
    
     Text(text = "这是首页")
    
     }
    
 }
    
  
    
 @Composable
    
 fun Mine(navController: NavController) {
    
     Box(modifier = Modifier.fillMaxSize(),
    
     contentAlignment = Alignment.Center) {
    
     Text(text = "这是个人中心")
    
     }
    
 }
    
  
    
 /** * 底部导航栏
    
  */
    
 class Compose_16Activity : ComponentActivity() {
    
  
    
     override fun onCreate(savedInstanceState: Bundle?) {
    
     super.onCreate(savedInstanceState)
    
     setContent {
    
         compose_16()
    
     }
    
  
    
     }
    
 }

注意:

1.一般颜色都是在主题设置,然后引用的,这里为了方便,没有在引用主题;

2.这里所用的icon资源需要一下依赖:

复制代码
    implementation "androidx.compose.material:material-icons-extended:$compose_version"

全部评论 (0)

还没有任何评论哟~