flutter + curved_navigation_bar (底部导航栏)
初始化的底部导航栏没有什么特色,项目开发又比较着急,因此我从pub.dev
中找到了一个简单、动效还比较好看的底部导航栏接入,它就是 curved_navigation_bar
,具体效果可查看下图,本文简单介绍一下该插件的接入方式,十分简单方便。
官方插件地址:pub.dev/packages/cu…
插件接入
大家按照官方文档去接入即可,虽然插件中代码最后一次更新是2年前,但是不影响最新版本的使用
// 命令行运行
flutter pub add curved_navigation_bar
// 或者在pubspec.yaml文件中添加
curved_navigation_bar: ^1.0.3
插件使用
底部bar的插件使用还是非常简单的,官方的例子也十分简洁明了,我这里使用了getx作为项目的底部框架,因此我主要介绍一下在getx中如何导入此插件
1. 创建数据列表
做简单事例,我创建了如下3个页面
- WebviewPage (H5交互的webview页面)
- DownloadPage (之前文档中创建的下载页面)
- UserPage (用户页面)
2. 实现角标和页面跳转绑定
controller.dart的代码:
// 创建类型MainTabModel
class MainTabModel {
late String tabName;
late String tabImg;
late String tabImgActivated;
late bool isDefault;
MainTabModel(
{required this.tabName,
required this.tabImg,
required this.tabImgActivated,
required this.isDefault});
MainTabModel.fromJson(Map<String, dynamic> json) {
tabName = json['tabName'];
tabImg = json['tabImg'];
tabImgActivated = json['tabImgActivated'];
isDefault = json['isDefault'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = <String, dynamic>{};
data['tabName'] = tabName;
data['tabImg'] = tabImg;
data['tabImgActivated'] = tabImgActivated;
data['isDefault'] = isDefault;
return data;
}
}
// main的controller中代码:
class MainController extends GetxController {
MainController();
// 创建页面controller,控制页面显示
final PageController pageController = PageController();
int currentIndex = 0;
List<Widget> pages = <Widget>[
const WebviewPage(),
const DownloadPage(),
const UserPage(),
];
// 填充页面角标变化数据
List<MainTabModel> mainTabs = <MainTabModel>[
MainTabModel(
tabName: "webview",
tabImg:
'https://miaohuapp-web.oss-cn-hangzhou.aliyuncs.com/beta/resources/main_tab/img/1688549054466833616.png',
tabImgActivated:
'https://miaohuapp-web.oss-cn-hangzhou.aliyuncs.com/beta/resources/main_tab/img_activated/1688549051061152900.png',
isDefault: false),
MainTabModel(
tabName: "下载",
tabImg:
'https://miaohuapp-web.oss-cn-hangzhou.aliyuncs.com/beta/resources/main_tab/img/1688549041307537463.png',
tabImgActivated:
'https://miaohuapp-web.oss-cn-hangzhou.aliyuncs.com/beta/resources/main_tab/img_activated/1688549034218176064.png',
isDefault: true),
MainTabModel(
tabName: "我",
tabImg:
'https://miaohuapp-web.oss-cn-hangzhou.aliyuncs.com/beta/resources/main_tab/img/1688549085949980932.png',
tabImgActivated:
'https://miaohuapp-web.oss-cn-hangzhou.aliyuncs.com/beta/resources/main_tab/img_activated/1688549082947472903.png',
isDefault: false),
];
void onTap() {}
@override
void onReady() {
//
super.onReady();
}
@override
void onClose() {
//
super.onClose();
}
// 导航栏切换
void onIndexChanged(int index) {
currentIndex = index;
update(["main"]);
}
// 点击角标跳转页面
void setCurrentIndex(index) {
currentIndex = index;
pageController.jumpToPage(index);
update(["main"]);
}
}
view.dart 中代码
class MainPage extends StatefulWidget {
const MainPage({super.key});
@override
State<MainPage> createState() => _MainPageState();
}
class _MainPageState extends State<MainPage>
with AutomaticKeepAliveClientMixin {
@override
bool get wantKeepAlive => true;
@override
Widget build(BuildContext context) {
super.build(context);
return const _MainViewGetX();
}
}
// 上述可忽略,目的是为了缓存页面不被销毁
class _MainViewGetX extends GetView<MainController> {
const _MainViewGetX({super.key});
// 主视图
Widget _buildView() {
return Scaffold(
extendBody: true,
resizeToAvoidBottomInset: false,
// 内容页
// body: DownloadPage(),
body: PageView(
physics: const NeverScrollableScrollPhysics(),
controller: controller.pageController,
onPageChanged: controller.onIndexChanged,
children: controller.pages,
),
// 在底部bar中添加组件,执行各项参数
bottomNavigationBar: CurvedNavigationBar(
onTap: (index) {
controller.setCurrentIndex(index);
},
letIndexChange: (index) => true,
color: const Color(0xFFF2FAFC),
buttonBackgroundColor: const Color(0xFFF2FAFC),
backgroundColor: Colors.transparent,
animationCurve: Curves.easeInOut,
animationDuration: const Duration(milliseconds: 500),
height: 60,
items: _randerItem()),
);
}
List<Widget> _randerItem() {
List<Widget> list = [];
for (var i = 0; i < controller.mainTabs.length; i++) {
MainTabModel info = controller.mainTabs[i];
list.add(Stack(
clipBehavior: Clip.none,
children: [
ImageWidget.url(
controller.currentIndex == i ? info.tabImgActivated : info.tabImg,
width: 30,
height: 30,
fit: BoxFit.cover,
),
],
));
}
return list;
}
@override
Widget build(BuildContext context) {
return GetBuilder<MainController>(
// init: Get.find<MainController>(),
id: "main",
builder: (_) => _buildView(),
);
}
}
如上,只需要简单的引入便可以获得一个动效还不错的底部bar效果。
转载自:https://juejin.cn/post/7356237910364078089