Flutter底部导航栏持久化插件persistent_bottom_nav_bar_plus的使用
Flutter底部导航栏持久化插件persistent_bottom_nav_bar_plus的使用
整体介绍
persistent_bottom_nav_bar_plus
是一个用于Flutter的底部导航栏插件,它提供了高度可定制的底部导航栏功能。 该插件支持在iOS和Android设备上使用,并且可以处理硬件/软件的Android返回按钮。
安装依赖
首先,在你的Flutter项目中添加以下依赖:
dependencies:
persistent_bottom_nav_bar_plus: any
导入包
在你的代码中导入 persistent_bottom_nav_bar_plus
包:
import 'package:persistent_bottom_nav_bar_plus/persistent_tab_view.dart';
声明控制器
声明 PersistentTabController
作为底部导航栏的控制器:
PersistentTabController _controller;
_controller = PersistentTabController(initialIndex: 0);
主要组件
主要组件是 PersistentTabView
,这个组件包含了Scaffold(基于CupertinoTabScaffold),所以不需要单独声明Scaffold。以下是一个示例代码:
class MyApp extends StatelessWidget {
const MyApp({Key key}) : super(key: key);
@override
Widget build(BuildContext context) {
return PersistentTabView(
context,
controller: _controller,
screens: _buildScreens(),
items: _navBarsItems(),
confineInSafeArea: true,
backgroundColor: Colors.white, // 默认白色背景
handleAndroidBackButtonPress: true, // 默认为true
resizeToAvoidBottomInset: true, // 默认为true
stateManagement: true, // 默认为true
hideNavigationBarWhenKeyboardShows: true, // 推荐设置'resize to avoid bottom inset'为true时使用此参数。默认为true
decoration: NavBarDecoration(
borderRadius: BorderRadius.circular(10.0),
colorBehindNavBar: Colors.white,
),
popAllScreensOnTapOfSelectedTab: true,
popActionScreens: PopActionScreensType.all,
itemAnimationProperties: ItemAnimationProperties( // 导航栏项目的动画属性。
duration: Duration(milliseconds: 200),
curve: Curves.ease,
),
screenTransitionAnimation: ScreenTransitionAnimation( // 屏幕切换动画
animateTabTransition: true,
curve: Curves.ease,
duration: Duration(milliseconds: 200),
),
navBarStyle: NavBarStyle.style1, // 选择导航栏样式
);
}
}
List<Widget> _buildScreens() {
return [
MainScreen(),
SettingsScreen()
];
}
List<PersistentBottomNavBarItem> _navBarsItems() {
return [
PersistentBottomNavBarItem(
icon: Icon(CupertinoIcons.home),
title: "Home",
activeColorPrimary: CupertinoColors.activeBlue,
inactiveColorPrimary: CupertinoColors.systemGrey,
),
PersistentBottomNavBarItem(
icon: Icon(CupertinoIcons.settings),
title: "Settings",
activeColorPrimary: CupertinoColors.activeBlue,
inactiveColorPrimary: CupertinoColors.systemGrey,
),
];
}
跳转屏幕
你可以使用以下函数来控制底部导航栏的可见性:
pushNewScreen(context, screen, withNavBar: true)
:在Android上不显示底部导航栏,在iOS上显示底部导航栏。pushNewScreenWithRouteSettings(context, settings, screen, withNavBar: true)
:与上面类似,但带有路由设置。
PersistentNavBarNavigator.pushNewScreen(
context,
screen: MainScreen(),
withNavBar: true, // 可选值,默认为true
pageTransitionAnimation: PageTransitionAnimation.cupertino,
);
PersistentNavBarNavigator.pushNewScreenWithRouteSettings(
context,
settings: RouteSettings(name: MainScreen.routeName),
screen: MainScreen(),
withNavBar: true,
pageTransitionAnimation: PageTransitionAnimation.cupertino,
);
部分有用的提示
-
弹出到导航图中的任何屏幕:
Navigator.of(context).popUntil((route) { return route.settings.name == "ScreenToPopBackTo"; });
-
弹回到导航图中的第一个屏幕:
Navigator.of(context).popUntil(ModalRoute.withName("/"));
Navigator.of(context).pushAndRemoveUntil( CupertinoPageRoute( builder: (BuildContext context) { return FirstScreen(); }, ), (_) => false, );
自定义导航栏样式
如果你想要自定义导航栏样式,请按照以下步骤操作:
- 定义自定义的导航栏项。请注意,你需要自己处理
onSelectedItem
和selectedIndex
函数以保持完整功能。你也可以定义自己的导航栏项模型而不是提供的PersistentBottomNavBarItem
。以下是一个示例代码:
class CustomNavBarWidget extends StatelessWidget {
final int selectedIndex;
final List<PersistentBottomNavBarItem> items; // 注意:你可以在这里定义自己的模型代替 `PersistentBottomNavBarItem`。
final ValueChanged<int> onItemSelected;
CustomNavBarWidget({
Key key,
this.selectedIndex,
@required this.items,
this.onItemSelected,
});
Widget _buildItem(PersistentBottomNavBarItem item, bool isSelected) {
return Container(
alignment: Alignment.center,
height: 60.0,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisSize: MainAxisSize.min,
children: <Widget>[
Flexible(
child: IconTheme(
data: IconThemeData(
size: 26.0,
color: isSelected
? (item.activeColorSecondary == null
? item.activeColorPrimary
: item.activeColorSecondary)
: item.inactiveColorPrimary == null
? item.activeColorPrimary
: item.inactiveColorPrimary),
child: item.icon,
),
),
Padding(
padding: EdgeInsets.only(top: 5.0),
child: Material(
type: MaterialType.transparency,
child: FittedBox(
child: Text(
item.title,
style: TextStyle(
color: isSelected
? (item.activeColorSecondary == null
? item.activeColorPrimary
: item.activeColorSecondary)
: item.inactiveColorPrimary,
fontWeight: FontWeight.w400,
fontSize: 12.0),
),
),
),
)
],
),
);
}
@override
Widget build(BuildContext context) {
return Container(
color: Colors.white,
child: Container(
width: double.infinity,
height: 60.0,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: items.map((item) {
int index = items.indexOf(item);
return Flexible(
child: GestureDetector(
onTap: () {
this.onItemSelected(index);
},
child: _buildItem(item, selectedIndex == index),
),
);
}).toList(),
),
),
);
}
}
- 在主
PersistentTabView
组件中,将navBarStyle
属性设置为NavBarStyle.custom
并传递自定义的 widget 到customWidget
属性中:
class MyApp extends StatelessWidget {
const MyApp({Key key}) : super(key: key);
@override
Widget build(BuildContext context) {
return PersistentTabView.custom(
context,
controller: _controller,
itemCount: items.length, // 这是在自定义样式的情况下必需的!传递导航栏项的数量。
screens: _buildScreens(),
confineInSafeArea: true,
handleAndroidBackButtonPress: true,
onItemSelected: (int) {
setState(() {}); // 这是为了更新导航栏如果Android返回按钮被按下
},
customWidget: CustomNavBarWidget(
items: _navBarsItems(),
selectedIndex: _controller.index,
onItemSelected: (index) {
setState(() {
_controller.index = index; // 注意:这是至关重要的的!不要错过它!
});
},
),
);
}
}
- 完成后,确保一些其他属性如
iconSize
、items
不需要在此处指定,因此可以忽略这些属性。为了控制屏幕底部的填充,使用bottomScreenPadding
。如果给定的bottomScreenPadding
量而自定义 widget 的的高度不足或反之,则可能会出现布局问题。
示例项目
对于更好的理解,请参考官方GitHub仓库中的示例项目:
https://github.com/SujitChanda/persistent_bottom_nav_bar_plus/tree/master/example
更多关于Flutter底部导航栏持久化插件persistent_bottom_nav_bar_plus的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter底部导航栏持久化插件persistent_bottom_nav_bar_plus的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
当然,下面是一个关于如何使用 persistent_bottom_nav_bar_plus
插件来在 Flutter 应用中实现持久化底部导航栏的示例代码。这个插件允许你创建一个持久的底部导航栏,即使在不同的页面之间切换时,导航栏的状态也能保持不变。
首先,确保你已经在 pubspec.yaml
文件中添加了 persistent_bottom_nav_bar_plus
依赖:
dependencies:
flutter:
sdk: flutter
persistent_bottom_nav_bar_plus: ^x.y.z # 请替换为最新版本号
然后,运行 flutter pub get
来安装依赖。
接下来,是主应用代码的实现。这里是一个完整的示例,展示了如何使用 persistent_bottom_nav_bar_plus
插件:
import 'package:flutter/material.dart';
import 'package:persistent_bottom_nav_bar_plus/persistent-theme.dart';
import 'package:persistent_bottom_nav_bar_plus/persistent_bottom_nav_bar.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Persistent Bottom Nav Bar Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: PersistentBottomNavBarDemo(),
);
}
}
class PersistentBottomNavBarDemo extends StatefulWidget {
@override
_PersistentBottomNavBarDemoState createState() => _PersistentBottomNavBarDemoState();
}
class _PersistentBottomNavBarDemoState extends State<PersistentBottomNavBarDemo> {
final List<PersistentBottomNavBarItem> _navItems = [
PersistentBottomNavBarItem(
icon: Icon(Icons.home),
title: ("Home"),
routeAndNavigatorFunction: (context) {
Navigator.push(
context,
MaterialPageRoute(builder: (context) => HomeScreen()),
);
},
),
PersistentBottomNavBarItem(
icon: Icon(Icons.search),
title: ("Search"),
routeAndNavigatorFunction: (context) {
Navigator.push(
context,
MaterialPageRoute(builder: (context) => SearchScreen()),
);
},
),
PersistentBottomNavBarItem(
icon: Icon(Icons.library_books),
title: ("Library"),
routeAndNavigatorFunction: (context) {
Navigator.push(
context,
MaterialPageRoute(builder: (context) => LibraryScreen()),
);
},
),
PersistentBottomNavBarItem(
icon: Icon(Icons.profile),
title: ("Profile"),
routeAndNavigatorFunction: (context) {
Navigator.push(
context,
MaterialPageRoute(builder: (context) => ProfileScreen()),
);
},
),
];
int _selectedIndex = 0;
@override
Widget build(BuildContext context) {
return PersistentTabView(
context,
screens: [
HomeScreen(),
SearchScreen(),
LibraryScreen(),
ProfileScreen(),
],
items: _navItems,
initialIndex: _selectedIndex,
confineInSafeArea: true,
backgroundColor: Colors.white,
handleBackPressure: true,
decoration: NavBarDecoration(
borderRadius: BorderRadius.circular(10),
colorBehindNavBar: Colors.white,
),
popActionScreens: PopActionScreensType.all,
itemAnimationProperties: ItemAnimationProperties(
duration: Duration(milliseconds: 200),
curve: Curves.ease,
),
screenTransitionAnimation: ScreenTransitionAnimation(
animateTabTransition: true,
curve: Curves.ease,
duration: Duration(milliseconds: 200),
),
navBarStyle: NavBarStyle.style12,
);
}
}
class HomeScreen extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Home Screen'),
),
body: Center(
child: Text('This is the Home Screen'),
),
);
}
}
class SearchScreen extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Search Screen'),
),
body: Center(
child: Text('This is the Search Screen'),
),
);
}
}
class LibraryScreen extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Library Screen'),
),
body: Center(
child: Text('This is the Library Screen'),
),
);
}
}
class ProfileScreen extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Profile Screen'),
),
body: Center(
child: Text('This is the Profile Screen'),
),
);
}
}
在这个示例中,我们定义了一个 PersistentBottomNavBarDemo
类,它包含了四个导航项(Home, Search, Library, Profile)。每个导航项都有一个图标、标题和一个导航函数,用于在点击时导航到相应的页面。PersistentTabView
组件用于显示底部导航栏和相应的页面。
这个示例展示了如何使用 persistent_bottom_nav_bar_plus
插件创建一个持久的底部导航栏,并确保导航栏的状态在切换页面时保持不变。你可以根据需要进一步自定义和扩展这个示例。