Flutter动画底部导航栏插件animated_notch_bottom_bar的使用
Flutter动画底部导航栏插件animated_notch_bottom_bar的使用
Animated Notch Bottom Bar
Animated Notch Bottom Bar 是一个Flutter插件,用于创建带有凹槽效果的底部导航栏。它允许你通过动画来改变选中项的位置,并且可以自定义凹槽的颜色、大小和其他属性。
Features
- 支持任何Widget作为底部栏子项
- 动画化凹槽朝向选定项移动
- 创建具有美丽动画效果的优化底部导航栏
- 支持类似iOS Tab View的模糊效果
Getting Started
首先,在pubspec.yaml
文件中添加依赖:
dependencies:
animated_notch_bottom_bar: ^1.0.0
然后在你的Dart代码中导入该包并开始使用它。
Basic Usage
下面是一个完整的示例,展示了如何将AnimatedNotchBottomBar
集成到项目中:
import 'dart:developer';
import 'package:animated_notch_bottom_bar/animated_notch_bottom_bar/animated_notch_bottom_bar.dart';
import 'package:flutter/material.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Animated Notch Bottom Bar',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: const MyHomePage(),
);
}
}
class MyHomePage extends StatefulWidget {
const MyHomePage({Key? key}) : super(key: key);
@override
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
/// Controller to handle PageView and also handles initial page
final _pageController = PageController(initialPage: 0);
/// Controller to handle bottom nav bar and also handles initial page
final NotchBottomBarController _controller = NotchBottomBarController(index: 0);
int maxCount = 5;
@override
void dispose() {
_pageController.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
/// widget list
final List<Widget> bottomBarPages = [
Page1(controller: (_controller)),
const Page2(),
const Page3(),
const Page4(),
const Page5(),
];
return Scaffold(
body: PageView(
controller: _pageController,
physics: const NeverScrollableScrollPhysics(),
children: List.generate(bottomBarPages.length, (index) => bottomBarPages[index]),
),
extendBody: true,
bottomNavigationBar: (bottomBarPages.length <= maxCount)
? AnimatedNotchBottomBar(
notchBottomBarController: _controller,
color: Colors.white,
showLabel: true,
textOverflow: TextOverflow.visible,
maxLine: 1,
shadowElevation: 5,
kBottomRadius: 28.0,
notchColor: Colors.black87,
removeMargins: false,
bottomBarWidth: 500,
showShadow: false,
durationInMilliSeconds: 300,
itemLabelStyle: const TextStyle(fontSize: 10),
elevation: 1,
bottomBarItems: const [
BottomBarItem(
inActiveItem: Icon(Icons.home_filled, color: Colors.blueGrey),
activeItem: Icon(Icons.home_filled, color: Colors.blueAccent),
itemLabel: 'Page 1',
),
BottomBarItem(
inActiveItem: Icon(Icons.star, color: Colors.blueGrey),
activeItem: Icon(Icons.star, color: Colors.blueAccent),
itemLabel: 'Page 2',
),
BottomBarItem(
inActiveItem: Icon(Icons.settings, color: Colors.blueGrey),
activeItem: Icon(Icons.settings, color: Colors.pink),
itemLabel: 'Page 3',
),
BottomBarItem(
inActiveItem: Icon(Icons.person, color: Colors.blueGrey),
activeItem: Icon(Icons.person, color: Colors.yellow),
itemLabel: 'Page 4',
),
],
onTap: (index) {
log('current selected index $index');
_pageController.jumpToPage(index);
},
kIconSize: 24.0,
)
: null,
);
}
}
/// add controller to check weather index through change or not. in page 1
class Page1 extends StatelessWidget {
final NotchBottomBarController? controller;
const Page1({Key? key, this.controller}) : super(key: key);
@override
Widget build(BuildContext context) {
return Container(
color: Colors.yellow,
child: Center(
child: GestureDetector(
behavior: HitTestBehavior.translucent,
onTap: () {
controller?.jumpTo(2);
},
child: const Text('Page 1'),
),
),
);
}
}
class Page2 extends StatelessWidget {
const Page2({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return Container(color: Colors.green, child: const Center(child: Text('Page 2')));
}
}
class Page3 extends StatelessWidget {
const Page3({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return Container(color: Colors.red, child: const Center(child: Text('Page 3')));
}
}
class Page4 extends StatelessWidget {
const Page4({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return Container(color: Colors.blue, child: const Center(child: Text('Page 4')));
}
}
class Page5 extends StatelessWidget {
const Page5({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return Container(color: Colors.lightGreenAccent, child: const Center(child: Text('Page 5')));
}
}
自定义选项
你可以根据需要调整以下参数来自定义底部导航栏的行为和外观:
removeMargins
: 移除边距,默认为false
bottomBarWidth
: 设置底部栏宽度(适用于Web和桌面应用)durationInMilliSeconds
: 设置动画持续时间showLabel
: 显示或隐藏标签itemLabelStyle
: 设置标签样式showShadow
: 是否显示阴影showBlurBottomBar
: 启用模糊效果blurOpacity
,blurFilterX
,blurFilterY
: 控制模糊效果的具体参数notchColor
,notchGradient
: 设置凹槽颜色或渐变色showTopRadius
,showBottomRadius
: 显示或隐藏圆角elevation
: 设置底部栏的高度bottomBarHeight
: 设置底部栏的高度
更多详细信息请参考官方文档或直接查看源码中的注释。
Migrating to 1.0.0+
从版本1.0.0
开始,NotchBottomBarController
被引入以控制动画,而不再使用PageController
。因此你需要更新你的代码来适应这一变化。
License
本插件遵循MIT许可协议。
如果你有任何问题或建议,请随时联系开发者团队!
更多关于Flutter动画底部导航栏插件animated_notch_bottom_bar的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter动画底部导航栏插件animated_notch_bottom_bar的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
当然,以下是如何在Flutter中使用animated_notch_bottom_bar
插件来实现带有动画效果的底部导航栏的代码示例。
首先,确保在你的pubspec.yaml
文件中添加animated_notch_bottom_bar
依赖:
dependencies:
flutter:
sdk: flutter
animated_notch_bottom_bar: ^最新版本号 # 请替换为实际最新版本号
然后,运行flutter pub get
来安装依赖。
接下来,在你的Flutter项目中,可以按照以下步骤实现带有动画效果的底部导航栏:
- 导入必要的包:
import 'package:flutter/material.dart';
import 'package:animated_notch_bottom_bar/animated_notch_bottom_bar.dart';
- 定义页面内容:
假设你有三个页面,分别为HomePage
、SearchPage
和ProfilePage
,可以简单地用Scaffold
和Center
来展示一些内容。
class HomePage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('Home')),
body: Center(child: Text('Home Page')),
);
}
}
class SearchPage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('Search')),
body: Center(child: Text('Search Page')),
);
}
}
class ProfilePage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('Profile')),
body: Center(child: Text('Profile Page')),
);
}
}
- 创建主应用:
使用AnimatedNotchBottomBar
来创建底部导航栏,并使用IndexedStack
来管理页面切换。
class MyApp extends StatefulWidget {
@override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> with SingleTickerProviderStateMixin {
int _selectedIndex = 0;
void _onItemTapped(int index) {
setState(() {
_selectedIndex = index;
});
}
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: Scaffold(
body: IndexedStack(
index: _selectedIndex,
children: [
HomePage(),
SearchPage(),
ProfilePage(),
],
),
bottomNavigationBar: AnimatedNotchBottomBar(
notchWidth: 24,
notchHeight: 6,
notchColor: Colors.white,
backgroundColor: Colors.blue,
items: [
AnimatedNotchBottomBarItem(
icon: Icon(Icons.home),
title: 'Home',
color: Colors.white,
),
AnimatedNotchBottomBarItem(
icon: Icon(Icons.search),
title: 'Search',
color: Colors.white,
),
AnimatedNotchBottomBarItem(
icon: Icon(Icons.person),
title: 'Profile',
color: Colors.white,
),
],
currentIndex: _selectedIndex,
onItemSelected: _onItemTapped,
animationDuration: 300,
),
),
);
}
}
void main() {
runApp(MyApp());
}
在这个示例中,我们:
- 定义了三个简单的页面:
HomePage
、SearchPage
和ProfilePage
。 - 在主应用
MyApp
中,使用IndexedStack
来根据_selectedIndex
切换页面。 - 使用
AnimatedNotchBottomBar
来创建底部导航栏,并设置了图标、标题、颜色等属性。 - 通过
onItemSelected
回调来更新_selectedIndex
,从而实现页面切换。
运行这个代码,你将看到一个带有动画效果的底部导航栏,能够在不同页面之间切换。