文章目录
- 1、准备工作
- 1.1 参考
- 1.2 依赖添加:
- 1.3 主要控件
- NavigationBar
- HorizontalPager、VerticalPager
- 2、功能描述:
- 3、实现过程
- 3.1 创建一个数据类
- 3.2 创建一个list变量
- 3.3 具体实现
- 3.3.1 创建共享的Pager状态
- 3.3.2 将页面索引与页面标题同步
- 3.3.3 创建协程作用域
- 3.3.4 使用HorizontalPager实现滑动效果
- 代码实现注意点
- 4、关键点
- 4.1 状态管理重构:
- 4.2 滑动与导航同步
1、准备工作
1.1 参考
组件BottomNavigation实现,版本变更后,Material 3 引入了 NavigationBar 作为 BottomNavigation 的替代品,提供更符合现代设计规范的外观和功能,使用使用 NavigationBar + NavigationBarItem进行实现。
1.2 依赖添加:
使用Bom的版本为2024.04.01,详细介绍见官网
1.3 主要控件
NavigationBar
NavigationBar 实现在一个应用程序的主要目的地之间移动
@Composable
fun NavigationBar(modifier: Modifier = Modifier,containerColor: Color = NavigationBarDefaults.containerColor,contentColor: Color = MaterialTheme.colorScheme.contentColorFor(containerColor),tonalElevation: Dp = NavigationBarDefaults.Elevation,windowInsets: WindowInsets = NavigationBarDefaults.windowInsets,content: @Composable RowScope.() -> Unit
)
HorizontalPager、VerticalPager
HorizontalPager控制控件左右移动,VerticalPager控制控件上下移动
@Composable
fun HorizontalPager(state: PagerState,modifier: Modifier = Modifier,contentPadding: PaddingValues = PaddingValues(0.dp),pageSize: PageSize = PageSize.Fill,beyondViewportPageCount: Int = PagerDefaults.BeyondViewportPageCount,pageSpacing: Dp = 0.dp,verticalAlignment: Alignment.Vertical = Alignment.CenterVertically,flingBehavior: TargetedFlingBehavior = PagerDefaults.flingBehavior(state = state),userScrollEnabled: Boolean = true,reverseLayout: Boolean = false,key: ((index: Int) -> Any)? = null,pageNestedScrollConnection: NestedScrollConnection = PagerDefaults.pageNestedScrollConnection(state,Orientation.Horizontal),snapPosition: SnapPosition = SnapPosition.Start,pageContent: @Composable PagerScope.(page: Int) -> Unit
2、功能描述:
在底部导航栏中设置按钮,点击按钮切换页面,或者将页面左右滑动
如图所示:
3、实现过程
3.1 创建一个数据类
data class FileBean(val icon:Int = -1,val title:String = "",
)
3.2 创建一个list变量
bottomNavigationList 变量声明需要的icon和title内容
val bottomNavigationList =mutableListOf(FileBean(icon = R.mipmap.icon_home_page,title = stringResource(R.string.home_text)),FileBean(icon = R.mipmap.icon_case_page,title = stringResource(R.string.case_text)),FileBean(icon = R.mipmap.icon_evidence_page,title = stringResource(R.string.evidence_text)),FileBean(icon = R.mipmap.icon_request_page,title = stringResource(R.string.request_text)),FileBean(icon = R.mipmap.icon_my_page,title = stringResource(R.string.my_text)),)
3.3 具体实现
3.3.1 创建共享的Pager状态
val pagerState = rememberPagerState(pageCount = { bottomNavigationList.size })
3.3.2 将页面索引与页面标题同步
val currentPageTitle by remember {derivedStateOf {bottomNavigationList[pagerState.currentPage].title}}
3.3.3 创建协程作用域
val coroutineScope = rememberCoroutineScope()
3.3.4 使用HorizontalPager实现滑动效果
val pagerState = rememberPagerState(pageCount = { bottomNavigationList.size })val currentPageTitle by remember {derivedStateOf {bottomNavigationList[pagerState.currentPage].title}}val coroutineScope = rememberCoroutineScope()
Scaffold(bottomBar = {NavigationBar(containerColor = Color.White) {bottomNavigationList.forEachIndexed { index, item ->NavigationBarItem(icon = {Icon(painter = painterResource(id = item.icon),contentDescription = item.title)},label = { Text(item.title) },selected = currentPageTitle == item.title,onClick = {// 点击导航项时平滑滚动到对应页面coroutineScope.launch {pagerState.animateScrollToPage(index)}},colors = NavigationBarItemDefaults.colors(indicatorColor = Color.Transparent,selectedIconColor = colorResource(R.color.agree_red),selectedTextColor = colorResource(R.color.agree_red),unselectedIconColor = colorResource(R.color.agree_grey),unselectedTextColor = colorResource(R.color.agree_grey),))}}}) { paddingValues ->//使用HorizontalPager实现滑动效果HorizontalPager(state = pagerState,modifier = Modifier.padding(paddingValues),verticalAlignment = Alignment.Top,beyondViewportPageCount = 0 //正常会预加载下一页,但是页面复杂会导致性能下降,将其设置为0) { pageIndex ->// 根据当前页面索引显示对应内容when (pageIndex) {0 -> HomePage()1 -> FilePage()2 -> VideoPage()3 -> RequestPage()4 -> MyPage()}}}
代码实现注意点
beyondViewportPageCount 字段
需要注意的是,使用HorizontalPager时会自动加载下一页,如果每一页面较为复杂的话,会影响性能,可以通过beyondViewportPageCount 字段控制页面的加载效果,但是会影响滑动的流畅度,可以选择进行设置。
4、关键点
4.1 状态管理重构:
使用 rememberPagerState 统一管理页面状态
通过 derivedStateOf 自动同步页面索引和标题
4.2 滑动与导航同步
// 点击导航项时滚动到对应页面
onClick = {coroutineScope.launch {pagerState.animateScrollToPage(index)}
}// HorizontalPager自动更新当前页面索引
HorizontalPager(state = pagerState) { pageIndex ->// 显示对应页面
}