【Flutter】底部导航栏实现 ( BottomNavigationBar 底部导航栏 | BottomNavigationBarItem 导航栏条目 | PageView )(一)

简介: 【Flutter】底部导航栏实现 ( BottomNavigationBar 底部导航栏 | BottomNavigationBarItem 导航栏条目 | PageView )(一)

文章目录

一、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(),
),


目录
相关文章
|
5月前
Flutter 小技巧之 ListView 和 PageView 的各种花式嵌套
Flutter 小技巧之 ListView 和 PageView 的各种花式嵌套 在 Flutter 中,ListView 和 PageView 是两个常用的控件,它们可以用于滑动展示大量内容的场景,且支持各种嵌套方式,本文将介绍其中的一些花式嵌套方式。
|
JSON Dart IDE
Flutter实现国际化
开发一个App,如果我们的App需要面向不同的语种(比如中文、英文、繁体等),那么我们需要对齐进行国际化开发
892 0
Flutter实现国际化
|
4月前
|
iOS开发
Flutter - 底部导航详解与案例示范
Flutter - 底部导航详解与案例示范
60 0
|
11月前
|
Android开发 iOS开发
Flutter应用开发,系统样式改不了?SystemChrome 状态栏、导航栏、屏幕方向……想改就改
Flutter应用开发,系统样式改不了?SystemChrome 状态栏、导航栏、屏幕方向……想改就改
|
11月前
|
UED 索引
Flutter仿写微信导航栏快速实现页面导航
Flutter仿写微信导航栏快速实现页面导航
|
移动开发 Android开发 索引
flutter之从零开始搭建(一)之 BottomNavigationBar
flutter之从零开始搭建(一)之 BottomNavigationBar
140 0
flutter之从零开始搭建(一)之 BottomNavigationBar
|
Dart IDE 开发工具
Flutter 图文并茂列表实现
Flutter使用 ListView 完成列表的构建,界面实现的关键工作实际是布局子元素的拆分。剩下的实现方式存在多种,看各人喜好。但是,需要注意避免过多嵌套导致代码不好维护,并需要提高复用性。
810 2
Flutter 图文并茂列表实现
|
数据安全/隐私保护 UED
Flutter 使用自定义fluro 路由实现访问权限控制
本篇介绍了利用 Fluro 路由管理实现路由权限拦截的两种方式,两种方式各有好处,使用过程中可以根据实际情况决定使用哪一种方法。
526 1
Flutter 使用自定义fluro 路由实现访问权限控制
|
存储 数据安全/隐私保护
Flutter App页面路由及路由拦截实现
直接使用页面跳转会带来诸多缺陷,通过路由管理可以降低页面耦合,提高代码的可维护性和权限控制。本篇介绍了 Flutter 的路由管理和拦截实现。
1149 1
Flutter App页面路由及路由拦截实现
|
存储 前端开发
Flutter 实现多选底部弹窗
本篇介绍了底部弹窗实现多选的方式,其中实现的方式还可以有很多种,例如直接在自定义组件中使用有状态组件。这里介绍的方法可以作为一个参考,通过动态构建有状态组件能够简单快速地实现底部弹窗的多选功能。
623 0
Flutter 实现多选底部弹窗