文章目录
一、Scaffold 组件
二、底部导航栏整体架构
三、BottomNavigationBar 底部导航栏
四、BottomNavigationBarItem 导航栏条目
五、PageView 组件
六、完整代码示例
七、相关资源
一、Scaffold 组件
Flutter 中的 Scaffold 组件实现了基础的材料设计 ( Material Design ) 可视化布局结构 ;
Scaffold 提供了显示左侧侧拉导航栏 , 底部导航 , 浮动按钮等 API ;
Scaffold 构造函数如下 :
class Scaffold extends StatefulWidget { /// Creates a visual scaffold for material design widgets. const Scaffold({ Key? key, this.appBar, // 顶部的标题栏 this.body, // 中间显示的核心部分 , 标题栏下面的部分都是 this.floatingActionButton, // 右下角的悬浮按钮 ( 可改变位置 ) this.floatingActionButtonLocation, this.floatingActionButtonAnimator, this.persistentFooterButtons, this.drawer, // 侧拉导航栏 this.onDrawerChanged, this.endDrawer, this.onEndDrawerChanged, this.bottomNavigationBar, this.bottomSheet, this.backgroundColor, this.resizeToAvoidBottomInset, this.primary = true, this.drawerDragStartBehavior = DragStartBehavior.start, this.extendBody = false, this.extendBodyBehindAppBar = false, this.drawerScrimColor, this.drawerEdgeDragWidth, this.drawerEnableOpenDragGesture = true, this.endDrawerEnableOpenDragGesture = true, this.restorationId, }) : assert(primary != null), assert(extendBody != null), assert(extendBodyBehindAppBar != null), assert(drawerDragStartBehavior != null), super(key: key);
二、底部导航栏整体架构
通过设置 Scaffold 组件的 bottomNavigationBar 字段 , 为其设置一个 BottomNavigationBar 底部导航栏组件 , 该底部导航栏的 item 设置图标与文字组件数组 , onTap 字段设置 ValueChanged<int> 点击回调方法 , 通过该方法设置当前选择的页面索引值 ;
Scaffold 组件的主题 body 字段设置 PageView 组件 , 该组件主要设置 PageController? controller 和 List<Widget> children 字段 , PageController 用于控制 PageView 中的页面跳转 , children 中就是 PageView 封装的多个界面组件 , 同一时间只显示一个 ;
三、BottomNavigationBar 底部导航栏
通过 Scaffold 组件的 bottomNavigationBar 字段 , 可以设置底部导航栏菜单 , 设置一个 BottomNavigationBar 组件 ;
BottomNavigationBar 组件中可设置 int currentIndex 当前的索引 , ValueChanged? onTap 点击事件 ,
BottomNavigationBar 组件需要设置组件的类型 , 在 BottomNavigationBarType? type 字段设置 , 有两个可选类型 , fixed 和 shifting ;
enum BottomNavigationBarType { /// BottomNavigationBar 导航栏底部的 BottomNavigationBarItem 宽度不变 fixed, /// BottomNavigationBar 导航栏底部的 BottomNavigationBarItem 组件的位置和大小 , /// 都会根据当前点击的选项而改变 , /// 改变的时候有切换动画 /// 选中的状态下显示底部图标的文本 /// 不选中的状态下隐藏底部的文本内容 shifting, }
BottomNavigationBar 的 List<BottomNavigationBarItem> items 字段接受 BottomNavigationBarItem 组件集合 ;
底部导航栏点击事件 , ValueChanged<int>? onTap 字段设置点击事件 , 传入的参数是点击的底部导航栏索引值 ;
BottomNavigationBar 构造函数 :
BottomNavigationBar({ Key? key, required this.items, this.onTap, this.currentIndex = 0, this.elevation, this.type, Color? fixedColor, this.backgroundColor, this.iconSize = 24.0, Color? selectedItemColor, this.unselectedItemColor, this.selectedIconTheme, this.unselectedIconTheme, this.selectedFontSize = 14.0, this.unselectedFontSize = 12.0, this.selectedLabelStyle, this.unselectedLabelStyle, this.showSelectedLabels, this.showUnselectedLabels, this.mouseCursor, this.enableFeedback, }) : assert(items != null), assert(items.length >= 2), assert( items.every((BottomNavigationBarItem item) => item.title != null) || items.every((BottomNavigationBarItem item) => item.label != null), 'Every item must have a non-null title or label', ), assert(0 <= currentIndex && currentIndex < items.length), assert(elevation == null || elevation >= 0.0), assert(iconSize != null && iconSize >= 0.0), assert( selectedItemColor == null || fixedColor == null, 'Either selectedItemColor or fixedColor can be specified, but not both' ), assert(selectedFontSize != null && selectedFontSize >= 0.0), assert(unselectedFontSize != null && unselectedFontSize >= 0.0), selectedItemColor = selectedItemColor ?? fixedColor, super(key: key);
代码示例 :
BottomNavigationBar( /// 设置当前的导航页面索引 currentIndex: _currentIndex, /// 导航栏按钮点击事件 onTap: (pageIndex) { /// 跳转到对应的导航页面 _pageController.jumpToPage(pageIndex); setState(() { _currentIndex = pageIndex; }); }, /// 图标和文本位置不变 type: BottomNavigationBarType.fixed, /// 底部导航栏的按钮条目 items: datas.map((TabData data) { /// 单个按钮条目 return BottomNavigationBarItem( // 普通状态下的图标 , 绿色 icon: Icon( data.icon, color: Colors.green, ), /// 选中状态下的图标 , 红色 activeIcon: Icon( data.icon, color: Colors.red, ), /// 与 text 类似 , 只能设置一个 label: data.title, ); }).toList(), ),
四、BottomNavigationBarItem 导航栏条目
BottomNavigationBar 中需要设置 BottomNavigationBarItem 数组元素 , 这就需要创建若干 BottomNavigationBarItem 组件 ;
BottomNavigationBarItem 中可以设置
默认图标 Widget icon
底部文案 Widget? title
选中状态图标 Widget activeIcon
背景颜色 Color? backgroundColor
BottomNavigationBarItem 组件构造函数 :
const BottomNavigationBarItem({ required this.icon, @Deprecated( 'Use "label" instead, as it allows for an improved text-scaling experience. ' 'This feature was deprecated after v1.19.0.' ) this.title, this.label, Widget? activeIcon, this.backgroundColor, this.tooltip, }) : activeIcon = activeIcon ?? icon, assert(label == null || title == null), assert(icon != null);
五、PageView 组件
PageView 组件最重要的两个字段 :
PageController? controller
List<Widget> children
PageController 用于控制 PageView 的跳转 , PageController 主要作用是调用 void jumpToPage(int page) 方法 , 进行页面跳转 ;
jumpToPage 页面跳转在底部菜单栏的 onTap 点击事件中调用 , 更新当前页面后 , 需要调用 setState 方法更新界面 ;
PageView 构造函数 :
PageView({ Key? key, this.scrollDirection = Axis.horizontal, // 设置滚动方向 垂直 / 水平 this.reverse = false, // 反向滚动 PageController? controller, // 滚动控制类 this.physics, // 滚动逻辑 , 不滚动 / 滚动 / 滚动到边缘是否反弹 this.pageSnapping = true, // 如果设置 false , 则无法进行页面手势捕捉 this.onPageChanged, // 页面切换时回调该函数 List<Widget> children = const <Widget>[], this.dragStartBehavior = DragStartBehavior.start, this.allowImplicitScrolling = false, this.restorationId, this.clipBehavior = Clip.hardEdge, }) : assert(allowImplicitScrolling != null), assert(clipBehavior != null), controller = controller ?? _defaultPageController, childrenDelegate = SliverChildListDelegate(children), super(key: key);
PageView 代码示例 :
/// 滑动组件 , 界面的核心元素 PageView( /// 控制跳转翻页的控制器 controller: _pageController, /// Widget 组件数组 , 设置多个 Widget 组件 children: datas.map((TabData data) { return Padding( /// 内边距 20 padding: const EdgeInsets.all(20.0), /// PageView 中单个显示的组件 child: TabContent(data: data), ); }).toList(), physics: NeverScrollableScrollPhysics(), ),