基本概念
BottomNavigationBar({
Key key,
@required List<BottomNavigationBarItem> items, //BNI数组,
ValueChanged<int> onTap, //其中一项被点击后的回调
int currentIndex: 0, //激活项的索引
double elevation: 8.0, //
BottomNavigationBarType type, //有fixed、shifting两种
Color fixedColor, //选择的颜色,'Either selectedItemColor or fixedColor can be specified, but not both'
Color backgroundColor, //背景颜色
double iconSize: 24.0,
Color selectedItemColor,
Color unselectedItemColor,
IconThemeData selectedIconTheme: const IconThemeData(),
IconThemeData unselectedIconTheme: const IconThemeData(),
double selectedFontSize: 14.0,
double unselectedFontSize: 12.0,
TextStyle selectedLabelStyle,
TextStyle unselectedLabelStyle,
bool showSelectedLabels: true, 是否显示选中的Item的文字
bool showUnselectedLabels //是否显示未选中的Item的文字
});
BottomNavigationBar通常在Scaffold中使用,如下
Scaffold(
appBar: AppBar(...),
body: Container(...),
bottomNavigationBar: BottomNavigationBar(....)
)
- appBar,即标题
- body,内容显示区域
- bottomNavigationBar,底部导航栏
items少于等于3个,type默认值为fixed;items四个或者以上,type默认值为shifting,默认的选中和未选中的颜色是根据type变化的
fixed模式是平分,而shifting模式是可以摇摆的
滑动切换
body: PageView.builder( //实现滑动切换
onPageChanged: (int index){
Provider.of<SelectedIndexProvider>(context, listen: false).changeIndex(index);
},
controller: _pageController,
itemCount: _bodyPages.length,
itemBuilder: (BuildContext context, int index){
return _bodyPages.elementAt(index);
}
),
用_pageController去控制页面的显示
void _onChangeIndex(BuildContext context, int index){
Provider.of<SelectedIndexProvider>(context, listen: false).changeIndex(index);
//bottomNavigationBar 和 PageView 关联
_pageController.animateToPage(index, duration: Duration(milliseconds: 300), curve: Curves.ease);
}
代码
import 'package:flutter/material.dart';
import 'package:fluttertoast/fluttertoast.dart';
import 'package:provider/provider.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:flutter_bee/pages/page_home.dart';
import 'package:flutter_bee/pages/page_navi.dart';
import 'package:flutter_bee/pages/page_project.dart';
import 'package:flutter_bee/pages/page_tree.dart';
import 'package:flutter_bee/pages/page_article_detail.dart';
import 'package:flutter_bee/common/strings.dart';
import 'package:flutter_bee/common/colors.dart';
import 'package:flutter_bee/provider/provider_selected_index.dart';
import 'package:flutter_bee/provider/provider_theme.dart';
class IndexPage extends StatelessWidget {
final PageController _pageController = PageController(initialPage: 0);
final List<Widget> _bodyPages = [
HomePage(),
TreePage(),
NaviPage(),
ProjectPage()
];
final List<BottomNavigationBarItem> _bottomItems= [
BottomNavigationBarItem(
icon: Icon(Icons.home),
title: Text(YStrings.home)
),
BottomNavigationBarItem(
icon: Icon(Icons.filter_list),
title: Text(YStrings.tree)
),
BottomNavigationBarItem(
icon: Icon(Icons.low_priority),
title: Text(YStrings.navi)
),
BottomNavigationBarItem(
icon: Icon(Icons.apps),
title: Text(YStrings.project)
),
];
@override
Widget build(BuildContext context) {
ScreenUtil.init(context, width: 750, height: 1334);//初始化屏幕数据
int themeIndex = Provider.of<ThemeProvider>(context).value;
Map theme = YColors.themeColor[themeIndex == null ? 0 : themeIndex];
int _selectedIndex = Provider.of<SelectedIndexProvider>(context).selectedIndex;
return Scaffold(
appBar: AppBar(
leading: Builder(
builder: (BuildContext context){
return _accountAvatar(context);
}
),
title: Text(_getTitleByIndex(_selectedIndex)),
centerTitle: true,
actions: <Widget>[
IconButton(
icon: Icon(Icons.search),
onPressed: _onSearch
)
],
),
// body: IndexedStack(
// index: _selectedIndex,
// children: _bodyPages,
// ),
body: PageView.builder( //实现滑动切换
onPageChanged: (int index){
Provider.of<SelectedIndexProvider>(context, listen: false).changeIndex(index);
},
controller: _pageController,
itemCount: _bodyPages.length,
itemBuilder: (BuildContext context, int index){
return _bodyPages.elementAt(index);
}
),
bottomNavigationBar: BottomNavigationBar(
type: BottomNavigationBarType.fixed,
fixedColor: theme['primaryColor'],
items: _bottomItems,
currentIndex: _selectedIndex,
onTap: (index)=> _onChangeIndex(context, index),
),
floatingActionButton: FloatingActionButton(
backgroundColor: theme['primaryColor'],
onPressed: _onShowToast,
tooltip: '点击选中最后一个',
child: Icon(Icons.add, color: Colors.white),
),
drawer: _showDrawer(context),
);
}
void _onSearch(){
}
String _getTitleByIndex(int index){
switch (index) {
case 0:
return YStrings.home;
case 1:
return YStrings.tree;
case 2:
return YStrings.navi;
case 3:
return YStrings.project;
default:
return YStrings.home;
}
}
void _onChangeIndex(BuildContext context, int index){
Provider.of<SelectedIndexProvider>(context, listen: false).changeIndex(index);
//bottomNavigationBar 和 PageView 关联
_pageController.animateToPage(index, duration: Duration(milliseconds: 300), curve: Curves.ease);
}
void _onShowToast(){
Fluttertoast.showToast(
msg: 'test',
textColor: Colors.white,
fontSize: 12,
backgroundColor: YColors.color_999,
gravity: ToastGravity.BOTTOM
);
}
Widget _showDrawer(BuildContext context){
return Drawer(
child: ListView(
padding: EdgeInsets.zero, //注意设置0
children: <Widget>[
_accountInfo(context),
ListTile(
leading: Icon(Icons.favorite_border),
title: Text(YStrings.favorite),
trailing: Icon(Icons.chevron_right),
onTap: (){},
),
ListTile(
leading: Icon(Icons.color_lens),
title: Text(YStrings.changeTheme),
trailing: Icon(Icons.chevron_right),
onTap: (){},
),
ListTile(
leading: Icon(Icons.share),
title: Text(YStrings.share),
trailing: Icon(Icons.chevron_right),
onTap: (){},
),
ListTile(
leading: Icon(Icons.info_outline),
title: Text(YStrings.aboute),
trailing: Icon(Icons.chevron_right),
onTap: (){},
),
Divider(),
ListTile(
leading: Icon(Icons.power_settings_new),
title: Text(YStrings.logout),
trailing: Icon(Icons.chevron_right),
onTap: (){},
),
],
),
);
}
Widget _accountInfo(BuildContext context){
return UserAccountsDrawerHeader(
currentAccountPicture: GestureDetector(
child: ClipOval(
child: Image.asset('lib/assets/images/avatar.png'),
),
),
otherAccountsPictures: <Widget>[
IconButton(
icon: Icon(Icons.stars, color: Colors.white),
onPressed: (){
Navigator.of(context).pop();
Navigator.push(
context,
MaterialPageRoute(builder: (context) => ArticleDetailPage(
title: YStrings.addStar,
url: YStrings.github
))
);
}
)
],
accountName: Text(
YStrings.proName,
style: TextStyle(fontWeight: FontWeight.bold, fontSize: ScreenUtil().setSp(40)),
),
accountEmail: Text(YStrings.github),
onDetailsPressed: (){},
);
}
/**
* 自定义leading
*/
Widget _accountAvatar(BuildContext context){
return InkWell(
child: Container(
padding: EdgeInsets.all(ScreenUtil().setWidth(15)),
child: ClipOval(
child: Image.asset(
'lib/assets/images/avatar.png',
),
)
),
onTap: (){
Scaffold.of(context).openDrawer();
},
);
}
}
参考链接
官方地址:api.flutter.dev/flutter/mat…
Flutter 底部导航栏BottomNavigationBar:blog.csdn.net/yechaoa/art…
Flutter笔记(一):BottomNavigationBar常见问题:www.jianshu.com/p/7274bad9f…