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

article/2025/7/28 17:00:51

文章目录

  • 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.hkcw.cn/article/DEfJNnLVdh.shtml

相关文章

由反汇编代码确定结构体的完整声明

C程序中遇到下面的代码 typedef struct {int left;a_struct a[CNT];int right; } b_struct;void test( int i, b_struct *bp) {int nbp->leftbp->right;a_struct *ap&bp->a[i];ap->x[ap->idx]n; } 下面是test函数的反汇编代码 结合C程序中的代码与test函数…

生成式人工智能:重塑社会的双刃剑与人类文明的抉择

普罗米修斯之火与文明的抉择 当古希腊神话中的普罗米修斯盗取天火赠予人间时,人类文明开启了从蒙昧走向理性的征程。今天,生成式人工智能(GenAI)正以类似的方式重塑人类认知的边界——它既是照亮未来的火炬,也是可能灼…

TestHubo V1.1.0版本发布,新增用例评审功能,确保测试用例质量,提升测试用例覆盖率

TestHubo是一款开源免费的测试管理工具,提供一站式测试解决方案,涵盖功能测试、接口测试、性能测试以及 Web 和 App 测试等多个维度。本周TestHubo V1.1.0版本发布,新增用例评审功能。 1、版本更新日志 新增 ➢ 用例评审:通过评…

正点原子Z15I ZYNQ 开发板发布!板载PCIe2.0、SPFx2、MIPI CSI等接口,资料丰富!

正点原子Z15I ZYNQ 开发板发布!板载PCIe2.0、SPFx2、MIPI CSI等接口,资料丰富! 正点原子Z15I ZYNQ开发板,核心板全工业级设计,主控芯片的型号是XC7Z015CLG485-2I。开发板由核心板+底板组成,外设…

易路 iBuilder:解构企业 AI 落地困境,重构智能体时代生产力范式

一、从大模型到智能体的产业跃迁 2024 年堪称中国人工智能产业的 "战略拐点" 之年。当 DeepSeek R1 模型以 "技术 价格" 双重普惠模式掀起行业震荡时,各企业纷纷意识到,大模型的真正价值不在于技术炫技,而在于成为企业…

DiTAR: Diffusion Transformer Autoregressive Modeling for Speech Generation

kaiming 文章的codepaper abstract LLM 预测连续embedding,直接接DiT。和kaiming-Autoregressive Image Generation without Vector Quantization的文章思路一样。- LLM是casual attention,和diffusion 一起训练,相比于full attention会有性…

AC220V整流滤波电路Multisim仿真

一、仿真电路: 二、遇到的问题 1、仿真运行保险丝会熔断,然后输出电压不对。 解:这里可能是整流桥的模型不对,更换了一个新的模型,仿真就可以正常运行了。 2、整流桥的电流方向和问题 正半周: 负半周&a…

【后端高阶面经:架构篇】50、数据存储架构:如何改善系统的数据存储能力?

一、数据存储架构设计核心原则 (一)分层存储架构:让数据各得其所 根据数据访问频率和价值,将数据划分为热、温、冷三层,匹配不同存储介质,实现性能与成本的平衡。 热数据层:访问频率>100次/秒。采用Redis集群存储高频访问数据(如用户登录态、实时交易数据),配合…

安卓逆向篇Smail 语法反编译签名重打包Activity 周期Hook 模块

常见安卓逆向工具及环境: 1 、安卓模拟器(最好 root 的真机) 2 、 Magisk&XP&LSP 框架 HOOK 环境 安装参考: https://blog.csdn.net/danran550/article/details/132256027 3 、 Jadx-Gui 反编译 Java 代码查看…

AWS云创建安全审计用户组

目标 创建一个安全审计的用户组。 解决

拉深工艺模块——回转体拉深件毛坯尺寸的确定(一)

回转体拉深件毛坯尺寸的确定 一、 坯料形状和尺寸确定的依据 体积不变原则:若拉深前后料厚不变(体积表面积厚度),拉伸前坯料表面积与拉伸后冲件表面积近似相等,得到坯料尺寸。 相似原则:拉深前坯料的形状…

最佳实践|互联网行业软件供应链安全建设的SCA纵深实践方案

在数字化转型的浪潮中,开源组件已成为企业构建云服务与应用的基石,但其引入的安全风险也日益凸显。某互联网大厂的核心安全研究团队,通过深度应用软件成分分析(SCA)技术,构建了一套覆盖开源组件全生命周期管…

【软件安装那些事 3 】CAD(2026 V60.7z) 安装教程(中文简体版)步骤完整不跳步 { 附软件提取下载链接,永久有效---------百度网盘 }

通过网盘分享的文件:CAD2026 V60.7z 安装包 中文 (永久有效) 链接: https://pan.baidu.com/s/122UXbOK9iGsD5Ld-lzrfAA?pwdneqd 提取码: neqd 1、解压完成后,打开【Setup】文件夹 2、鼠标右击【Setup】…

智能柜I立控信息I产品介绍

在数字化浪潮席卷各行各业的今天,智能存储解决方案正成为企业提升运营效率、优化资产管理的重要工具。LKONE品牌推出的智能柜产品,凭借其创新的技术配置和人性化的功能设计,为用户带来了全新的智能存储体验。 一、特殊勤务单位装备管理面临的…

特伦斯 S75 电钢琴:奏响音乐新时代的华章

当今音乐市场中,电钢琴领域蓬勃发展。随着生活水平提升和音乐教育普及,它成众多音乐爱好者与家庭的首选。当下电钢琴市场走向显著,技术创新、消费升级推动发展,应用场景不断拓展,日益多元化。 在这样的市场大环境下&a…

【Linux】权限相关指令

前言: 上两篇文章我们讲到了,关于Linux中的基础指令。 【Linux】初见,基础指令-CSDN博客【Linux】初见,基础指令-CSDN博客 本文我们来讲Linux中关于权限中的一些指令 shell命令 Linux严格来说是一个操作系统,我们称之…

day14 leetcode-hot100-26(链表5)

142. 环形链表 II - 力扣(LeetCode) 1.哈希表 思路 与上一个一模一样,基本上没有区别,就是寻找是否存储过该节点。具体思路如下 day14 leetcode-hot100-25(链表4)-CSDN博客 具体代码 /*** Definition…

新能源汽车与油车销量

中国油车与新能源车销量对比(2022-2025年) ‌1. 市场份额演化(2022-2025年)‌ ‌年份‌ ‌新能源车销量 (渗透率)‌ ‌燃油车销量 (渗透率)‌ ‌关键事件‌ ‌2022‌ 688.7万辆…

大语言模型 23 - MCP 自动操作 自动进行联网检索 扩展MCP能力

点一下关注吧!!!非常感谢!!持续更新!!! Java篇: MyBatis 更新完毕目前开始更新 Spring,一起深入浅出! 大数据篇 300: Hadoop&…

通用的防御框架,用于抵御(多模态)大型语言模型的越狱攻击

大家读完觉得有帮助记得关注!!! 摘要 尽管(多模态)大型语言模型(LLMs)因其卓越的能力而受到广泛关注,但它们仍然容易受到越狱攻击。已经提出了各种防御方法来防御越狱攻击&#xff…