当前位置: 首页 > java >正文

Compose仿微信底部导航栏NavigationBar :底部导航控制滑动并移动

文章目录

  • 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 ->// 显示对应页面
}
http://www.xdnf.cn/news/9904.html

相关文章:

  • 大数据时代的利剑:Bright Data网页抓取与自动化工具共建高效数据采集新生态
  • 语法糖介绍(C++ Python)
  • Flutter实现不规则瀑布流布局拖拽重排序
  • 嵌入式自学第三十一天
  • 反范式设计应用场景解析
  • 【飞控】ChibiOS与NuttX
  • 【C++】ldd常见命令
  • st倍增(st表)
  • 运行apt install为何卡顿 (by quqi99)
  • Nginx版本平滑迁移方案
  • @ModelAttribute、@RequestBody、@RequestParam、@PathVariable 注解对比
  • 农村土地承包经营权二轮延包—归户表
  • day13 leetcode-hot100-22(链表1)
  • cf2059B
  • 【模板-指南】
  • 12:遨博机器人开发
  • 软考-系统架构设计师-第七章 软件工程基础知识
  • 学生管理系统V2.0
  • PCA主成分分析与Python应用
  • View的工作流程——measure
  • Linux实操篇-进程管理
  • 防火墙ASPF(针对应用层包过滤技术) FTP(主动模式)
  • 为什么我开始用 Data.olllo 做数据处理了?
  • langchain框架-对比分析chain的三种实现方式
  • 【二】10.L并发与竞争机制
  • HOW - 简历和求职面试宝典(三)
  • Python多版本共存指南:使用虚拟环境实现不同Python版本的灵活切换
  • 【CBAP50技术手册】#29 Mind Mapping(思维导图):BA(业务分析师)的“思维引擎”
  • Debian:自由操作系统的精神图腾与技术基石
  • Python 基于卷积神经网络手写数字识别