Flutter for OpenHarmony二手物品置换App实战 - 底部导航实现
本文介绍了Flutter中实现底部导航栏的方案,重点讲解了如何使用ConvexAppBar库创建中间凸起的导航栏样式。文章包含以下内容:1) 完整代码实现,使用IndexedStack保持页面状态;2) 对比IndexedStack和PageView两种导航方式的优缺点;3) 展示ConvexAppBar提供的多种样式选项;4) 总结实现核心要点。该方案适用于需要突出核心功能(如发布按钮)的移动应

底部导航栏是App的核心交互组件,用户通过它在主要功能模块之间切换。我们的底部导航有四个Tab:首页、发布、消息、我的。其中"发布"按钮做成中间凸起的样式,突出这个核心功能。
完整代码实现
import 'package:flutter/material.dart';
import 'package:convex_bottom_bar/convex_bottom_bar.dart';
import 'home/home_page.dart';
import 'publish/publish_page.dart';
import 'message/message_page.dart';
import 'profile/profile_page.dart';
class MainPage extends StatefulWidget {
const MainPage({super.key});
State<MainPage> createState() => _MainPageState();
}
这里导入了convex_bottom_bar包来实现中间凸起的导航栏效果,这个第三方库比Flutter原生的BottomNavigationBar更灵活。MainPage使用StatefulWidget是因为需要管理当前选中Tab的索引状态,点击不同Tab时要更新界面。
class _MainPageState extends State<MainPage> {
int _currentIndex = 0;
final List<Widget> _pages = [
const HomePage(),
const PublishPage(),
const MessagePage(),
const ProfilePage(),
];
_currentIndex记录当前选中的Tab,默认是0即首页。_pages列表存放四个主要页面实例,顺序要和底部Tab对应。用const修饰可以让Flutter复用这些Widget实例,提升性能。
Widget build(BuildContext context) {
return Scaffold(
body: IndexedStack(
index: _currentIndex,
children: _pages,
),
bottomNavigationBar: ConvexAppBar(
style: TabStyle.fixedCircle,
backgroundColor: Colors.white,
activeColor: const Color(0xFF07C160),
color: Colors.grey,
items: const [
TabItem(icon: Icons.home, title: '首页'),
TabItem(icon: Icons.add_circle, title: '发布'),
TabItem(icon: Icons.message, title: '消息'),
TabItem(icon: Icons.person, title: '我的'),
],
initialActiveIndex: _currentIndex,
onTap: (index) {
setState(() {
_currentIndex = index;
});
},
),
);
}
}
页面主体用IndexedStack,它会同时持有所有子页面但只显示当前选中的那个。好处是切换Tab时页面状态不会丢失,比如首页滚动位置会保持。ConvexAppBar的style: TabStyle.fixedCircle让中间按钮固定凸起。activeColor用主题绿色,onTap回调通过setState更新索引触发界面刷新。
IndexedStack和PageView的对比
// IndexedStack的特点
IndexedStack(
index: _currentIndex,
children: _pages, // 所有页面都会被创建
)
IndexedStack适合Tab数量少、需要保持状态的场景,所有页面在首次渲染时就会创建,切换只是改变显示哪个。
// PageView的特点
PageView(
controller: _pageController,
onPageChanged: (index) {
setState(() => _currentIndex = index);
},
children: _pages,
)
PageView支持滑动切换,但默认不保持页面状态。如果需要保持,要配合AutomaticKeepAliveClientMixin使用。咱们这个App只有4个Tab,用IndexedStack完全够用。
ConvexAppBar的其他样式
// 选中哪个哪个凸起
ConvexAppBar(
style: TabStyle.react,
// ...
)
// 选中的变成圆形凸起
ConvexAppBar(
style: TabStyle.reactCircle,
// ...
)
// 文字在图标下方的凹槽里
ConvexAppBar(
style: TabStyle.textIn,
// ...
)
// 切换时有翻转动画
ConvexAppBar(
style: TabStyle.flip,
// ...
)
ConvexAppBar提供了多种样式可选,react是选中哪个哪个凸起,reactCircle是圆形凸起,textIn把文字放在凹槽里,flip有翻转动画。根据产品需求选择合适的样式,我们用fixedCircle是因为发布功能重要,要一直突出显示。
小结
这篇讲解了底部导航的实现,使用ConvexAppBar实现中间凸起效果,IndexedStack保持页面状态。核心就是管理好Tab索引,点击时更新状态切换页面。
欢迎加入开源鸿蒙跨平台社区:https://openharmonycrossplatform.csdn.net
更多推荐
所有评论(0)