1. BottomNavigationBar 详解
BottomNavigationBar 类
的构造函数BottomNavigationBarItem
类 (items 列表 成员的类型)
BottomNavigationBarType 枚举
2. BottomNavigationBar 示范项目
3. 项目效果
显示在应用程序底部的 material Widget,用于在少量视图中进行选择,通常在 3 - 5 个之间。底部导航栏由文本标签、图标或两者形式的多个项目组成,布置在一块 material 的顶部。它在应用程序的顶级视图之间提供快速导航。对于更大的屏幕比如10.6存及以上大小的平板,侧边导航比底部导航栏可能更合适。底部导航栏通常与Scaffold
一起使用,它作为Scaffold.bottomNavigationBar
参数提供。
底部导航栏的类型会更改其项目的显示方式。如果未指定,则在少于 4 个项目时,自动设置为BottomNavigationBarType.fixed
,否则设置为BottomNavigationBarType.shifting
。
项目的长度必须至少为两个,并且每个项目的图标和标题/标签不得为空。
BottomNavigationBar 类
的构造函数BottomNavigationBar({
Key? key, // Widget、Element 和 SemanticsNode 的标识符。
required List<BottomNavigationBarItem> items, // 带有图标和标题的按钮的列表,见 1.2 节
ValueChanged<int>? onTap,
int currentIndex = 0, // 当前活动的BottomNavigationBarItem 的项目索引。
double? elevation, // 用于定义该 BottomNavigationBar 相对于其父级的`z`轴坐标,如果为 null,则默认为8.0。
BottomNavigationBarType? type, // 定义 BottomNavigationBar 的布局和行为。见 1.3 节
Color? fixedColor, // 颜色,为ARGB 格式的不可变 32 位颜色值。
Color? backgroundColor, // 背景填充色,为ARGB 格式的不可变 32 位颜色值。
double iconSize = 24.0, // 所有 BottomNavigationBarItem 图标的大小。[...]
Color? selectedItemColor, // 选定的 BottomNavigationBarItem.icon 和 BottomNavigationBarItem.title 的颜色。[...]
Color? unselectedItemColor,
IconThemeData? selectedIconTheme, // 当前选中的BottomNavigationBarItem.icon 中图标的大小、不透明度和颜色 。[...]
IconThemeData? unselectedIconTheme, // 当前未选中的BottomNavigationBarItem.icon 中图标的大小、不透明度和颜色 。[...]
double selectedFontSize = 14.0, // BottomNavigationBarItem标签被选中时 的字体大小。[...]
double unselectedFontSize = 12.0,
TextStyle? selectedLabelStyle,
TextStyle? unselectedLabelStyle, // 未选中时 ,BottomNavigationBarItem标签 的TextStyle 。
bool? showSelectedLabels, // 是否为选定的BottomNavigationBarItem显示标签。
bool? showUnselectedLabels, // 是否为未选中的BottomNavigationBarItem显示标签。
MouseCursor? mouseCursor,
bool? enableFeedback,
BottomNavigationBarLandscapeLayout? landscapeLayout
})
创建底部导航栏,通常用作 Scaffold
的 Scaffold.bottomNavigationBar
参数。items
的长度必须至少为两个,并且每个项目的图标和标签不能为空。
BottomNavigationBarType.fixed
,否则使用BottomNavigationBarType.shifting
。selectedLabelStyle.color
和 unselectedLabelStyle.color
值为非空,将使用它们来代替selectedItemColor
和 unselectedItemColor
。IconThemeDatas
,您必须同时提供selectedIconTheme
和 unselectedIconTheme
,并且必须同时设置 IconThemeData.color
和IconThemeData.size
。selectedLabelStyle.fontSize
和 selectedFontSize
,将使用 selectedLabelStyle.fontSize
。showSelectedLabels
为null
,则使用bottonnavigationbarthemedata.showselectedlables
。如果bottonnavigationbarthemdata.showSelectedLabels
为null
,则showSelectedLabels
默认为true
。showUnselectedLabels
为空,则使用bottonnavigationbarthemedata.showunselectedlables
。如果bottonnavigationbarthedata.showselectedlabels
为空,则当类型为BottomNavigationBarType.fixed
时,showUnselectedLabels
默认为true
,当类型为BottomNavigationBarType.shifting
时,showUnselectedLabels
默认为false
。BottomNavigationBarItem
类 (items 列表 成员的类型)这个类很少单独使用。它通常嵌入在上面的底部导航小部件之一中。它一般是 material 的 BottomNavigationBar
或带有图标和标题 的 iOS 主题 CupertinoTabBar
中的交互式按钮。
其构造函数:
const BottomNavigationBarItem({
required Widget icon,
@Deprecated('Use "label" instead, as it allows for an improved text-scaling experience. ' 'This feature was deprecated after v1.19.0.') Widget? title,
String? label,
Widget? activeIcon,
Color? backgroundColor,
String? tooltip
})
名称 | 描述1 | 描述2 | 描述3 |
---|---|---|---|
activeIcon |
Widget |
final |
选择此底部导航项时显示的替代图标。[…] |
backgroundColor |
Color ? |
final | material BottomNavigationBar 的背景径向动画的颜色。[…] |
hashCode |
int |
read-only , inherited |
此对象的哈希码。[…] |
icon |
Widget |
final | 项目的图标。[…] |
label |
String ? |
final | BottomNavigationBarItem 的文本标签。[…] |
runtimeType |
Type |
read-only , inherited |
对象的运行时类型的表示。 |
title |
Widget ? |
final |
项目的标题。如果未提供标题,则只有在 Material Design BottomNavigationBar中未使用时才会显示该图标。[…]@Deprecated (‘使用 “label” 代替,因为它可以改善文本缩放体验。’ ‘此功能在 v1.19.0 之后被弃用。’) |
rtooltip |
String? | final | 当用户长按该项目时 ,此 BottomNavigationBarItem 的工具提示中显示的文本。[…] |
noSuchMethod()
noSuchMethod(Invocation invocation) → dynamic
在访问不存在的方法或属性时调用。[…]
toString()
toString() → String
此对象的字符串表示形式。[…]
==
operator ==(Object other) → bool
相等运算符。[…]
BottomNavigationBarType 枚举
fixed → const BottomNavigationBarType
底部导航栏的底部导航栏具有固定宽度
。如果固定则主要是体现在当点击某个导航按钮时,被点击的按钮不会移动也不会改变大小。
const BottomNavigationBarType(0)
shifting → const BottomNavigationBarType
底部导航栏底部导航栏的位置和大小会产生动画,当轻击标签时,标签会淡入。
const BottomNavigationBarType(1)
values → const List
此枚举中值的常量列表,按其声明顺序排列。
项目入口:main.dart
import 'package:flutter/material.dart';
import 'tabsPage/index.dart';
void main() => runApp(const MyApp());
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
// title: 'Flutter Demo',
theme: ThemeData(
// This is the theme of your application.
primarySwatch: Colors.orange,
),
home: const Tabs());
}
}
底部导航控制:tabsPage/index.dart
import 'package:flutter/material.dart';
import 'Page1.dart';
import 'Page2.dart';
import 'Page3.dart';
import 'Page4.dart';
class Tabs extends StatefulWidget {
const Tabs({Key? key}) : super(key: key);
@override
_TabsState createState() => _TabsState();
}
class _TabsState extends State<Tabs> {
int _selectedIndex = 0; // 用作被选中的 Tab 的索引号
final List _tabPages = [
const Page1(),
const Page2(),
const Page3(),
const Page4()
]; // 列举所有 Tab 控制切换将用到的页面
@override
Widget build(BuildContext context) {
return Scaffold(
body: _tabPages[_selectedIndex],
bottomNavigationBar: BottomNavigationBar(
selectedFontSize: 12.0, // 被选中时的字体大小
unselectedFontSize: 14.0, // 未被选中时的字体大小
showSelectedLabels: true, // 被选中时是否显示Label
showUnselectedLabels: true, // 未被选中时是否显示Label
enableFeedback: true, //点击会产生咔嗒声,长按会产生短暂的振动
selectedItemColor: Colors.orange, // 设置被选中时的图标颜色
unselectedItemColor: Colors.grey, // 设置未被选中时的图标颜色
items: const <BottomNavigationBarItem>[
BottomNavigationBarItem(
icon: Icon(
Icons.home,
size: 24.0,
),
label: '工作室',
backgroundColor: Colors.white,
),
BottomNavigationBarItem(
icon: Icon(Icons.event_note, size: 24.0),
label: '数据',
backgroundColor: Colors.white,
),
BottomNavigationBarItem(
icon: Icon(Icons.account_box_outlined, size: 24.0),
label: '通讯录',
backgroundColor: Colors.white,
),
BottomNavigationBarItem(
icon: Icon(Icons.person, size: 24.0),
label: '我的',
backgroundColor: Colors.white,
),
],
// 设置当前(即被选中时)页面
currentIndex: _selectedIndex,
// 当点击其中一个[items]被触发
onTap: (int index) {
setState(() {
/*
* item 被点中时更改当前索引。
* 其中,currentIndex 字段设置的值时响应式的
* 新版dart不用this.
*/
_selectedIndex = index;
});
},
),
);
}
}
底部导航得具体页面:
page1
import 'package:flutter/material.dart';
enum WhyFarther { harder, smarter, selfStarter, tradingCharter }
class Page1 extends StatefulWidget {
const Page1({Key? key}) : super(key: key);
@override
_Page1State createState() => _Page1State();
}
class _Page1State extends State<Page1> {
set _selection(WhyFarther _selection) {}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text("JcStdio"), actions: <Widget>[
IconButton(
icon: const Icon(Icons.search),
onPressed: () {},
),
PopupMenuButton<WhyFarther>(
onSelected: (WhyFarther result) {
setState(() {
_selection = result;
});
},
icon: const Icon(
Icons.add_circle_outline,
size: 24.0,
),
itemBuilder: (BuildContext context) => <PopupMenuEntry<WhyFarther>>[
PopupMenuItem<WhyFarther>(
value: WhyFarther.selfStarter,
child: Row(
children: const [
Icon(
Icons.qr_code_scanner_outlined,
size: 24.0,
),
Text('扫一扫')
],
)),
PopupMenuItem<WhyFarther>(
value: WhyFarther.tradingCharter,
child: Row(
children: const [
Icon(
Icons.person_add,
size: 24.0,
),
Text('添加朋友')
],
)),
],
)
]),
body: const Text('这里是 jcstdio: jclee95的个人工作室,欢迎你的到来!'),
);
}
}
page2
import 'package:flutter/material.dart';
class Page2 extends StatefulWidget {
const Page2({Key? key}) : super(key: key);
@override
_Page2State createState() => _Page2State();
}
class _Page2State extends State<Page2> {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text("数据")),
body: const Text('欢迎浏览数据中心页...'),
);
}
}
page3
import 'package:flutter/material.dart';
import '/datas/listData.dart';
// import '/datas/usercard.dart';
class Page3 extends StatefulWidget {
const Page3({Key? key}) : super(key: key);
@override
_Page3State createState() => _Page3State();
}
class _Page3State extends State<Page3> {
List<Widget> _listData() {
var tempList = listData.map((value) {
return ListTile(
leading: Image.network(value["imageurl"]),
title: Text(value["title"]),
subtitle: Text(value["author"]));
});
return tempList.toList();
}
// UserCard
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text("通讯录"),
),
body: ListView(
children: _listData(),
));
}
}
page4
import 'package:flutter/material.dart';
class Page4 extends StatefulWidget {
const Page4({Key? key}) : super(key: key);
@override
_Page3State createState() => _Page3State();
}
class _Page3State extends State<Page4> {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text("我的"),
),
body: const Text('欢迎来到个人中心!'));
}
}![请添加图片描述](https://img-blog.csdnimg.cn/719015957bcf4228bd9e87902cc7546d.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAamNMZWU5NQ==,size_20,color_FFFFFF,t_70,g_se,x_16)