【Flutter】底部导航栏页面框架 ( BottomNavigationBar 底部导航栏 | PageView 滑动页面 | 底部导航与滑动页面关联操作 )(一)

简介: 【Flutter】底部导航栏页面框架 ( BottomNavigationBar 底部导航栏 | PageView 滑动页面 | 底部导航与滑动页面关联操作 )(一)

文章目录

一、BottomNavigationBar 底部导航栏

二、PageView 滑动页面

三、BottomNavigationBar 与 PageView 关联

四、完整代码示例

1、核心导航组件

2、四个切换页面

3、应用启动主界面

4、运行效果

五、相关资源





一、BottomNavigationBar 底部导航栏


在 Scaffold 的 bottomNavigationBar 属性设置底部导航栏 ;


设置当前索引 : BottomNavigationBar的 currentIndex 属性设置当前底部导航栏的选中索引 , 为其设置一个变量 , 改变该变量值后 , 通过 setState 方法更新 UI 显示 ;


设置点击方法 : BottomNavigationBar 的 onTap 属性设置点击方法 , 传入 index 索引 , 该索引值是被点击的按钮索引 , 在该方法中主要操作当前的 currentIndex 属性变量 , 以及 PageView 页面跳转 ;


底部按钮设置 : BottomNavigationBar 的 item 属性设置若干 BottomNavigationBarItem 类型的点击按钮 ;



代码示例 :


bottomNavigationBar: BottomNavigationBar(
        /// 当前选中的导航索引
        currentIndex: _currentIndex,
        /// 底部导航栏的点击方法
        onTap: (index) {
          // 控制 PageView 跳转到指定的页面
          _pageController.jumpToPage(index);
          setState(() {
            // 更新当前的索引值
            _currentIndex = index;
          });
        },
        /// 设置底部的若干点击导航栏点击按钮
        /// 注意该 List<BottomNavigationBarItem> items
        /// 中的按钮顺序 , 要与 PageView 中的页面顺序必须保持一致
        /// 个数个顺序都要保持一致
        items: datas.map((data) {
          return BottomNavigationBarItem(
            /// 默认状态下的图标, 灰色
            icon: Icon(
              data.icon,
              color: Colors.grey,
            ),
            /// 选中状态下的图标, 红色
            activeIcon: Icon(
              data.icon,
              color: Colors.red,
            ),
            /// 根据当前页面是否选中 , 确定
            title: Text(
              data.title,
              style: TextStyle(
                /// 如果是选中状态 , 则设置红色
                /// 如果是非选中状态, 则设置灰色
                  color: _currentIndex == data.index ? Colors.red : Colors.grey),
            ),
          );
        }).toList(),
      )




二、PageView 滑动页面


PageView 作为显示的主体组件 , 设置给 Scaffold 的 body 字段 , 主要设置以下三个参数 ;


控制器 : 在 PageView 的 controller 参数设置 , PageController 类型 , 主要用于控制 PageView 的页面跳转 ;


滑动回调事件 : onPageChanged 参数设置滑动回调事件 , 传入 index 索引值 , 在该事件中 , 调用 setState 方法 , 更新底部导航栏 BottomNavigationBar 的当前索引值 , 并更新 UI 界面 ;


显示组件 : 在 children 参数中设置 Widget 数组即可 , 组件类型只要是 Widget 就行 ;



代码示例 :


/// 滑动组件 , 界面的核心元素
body: PageView(
  /// 控制跳转翻页的控制器
  controller: _pageController,
  /// 页面滑动
  /// 这里设置 PageView 页面滑动也能
  onPageChanged: (index) {
    setState(() {
      // 更新当前的索引值
      _currentIndex = index;
    });
  },
  /// Widget 组件数组 , 设置多个 Widget 组件
  /// 同一时间只显示一个页面组件
  children: [
    HomePage(), // 首页
    ImagePage(), // 图片页
    SearchPage(), // 搜索页
    SettingPage(), // 个人设置页
  ],
),






三、BottomNavigationBar 与 PageView 关联


BottomNavigationBar 被动设备选中状态 : BottomNavigationBar 的索引通过一个在组件内部定义的私有变量 _currentIndex 控制 , 将该 _currentIndex 变量设置给底部导航栏 BottomNavigationBar 的 currentIndex 参数 , 之后可以通过调用 setState 方法修改 _currentIndex 私有变量 , 即可控制 BottomNavigationBar 的选中状态 ;


BottomNavigationBar 主动设置选中状态 : 在 BottomNavigationBar 的 onTap 参数中 , 可以获取点击的按钮索引 , 然后调用 PageView 的 PageController 的 jumpToPage 方法 实现相应的界面跳转 ;


BottomNavigationBar(
  /// 当前选中的导航索引
  currentIndex: _currentIndex,
  /// 底部导航栏的点击方法
  onTap: (index) {
    // 控制 PageView 跳转到指定的页面
    _pageController.jumpToPage(index);
    setState(() {
      // 更新当前的索引值
      _currentIndex = index;
    });
  },
}



PageView 被动设置选中状态 : 在 BottomNavigationBar 底部导航栏中点击导航按钮 , 切换页面 , 使用 PageView 的 PageController 的 jumpToPage 方法进行页面跳转 ;


PageView 主动设置选中状态 : 滑动 PageView 界面 , 会回调 PageView 中的 onPageChanged 方法 , 在此处调用 setState 方法 , 在该方法中设置 _currentIndex 的值 , 进而更新 BottomNavigationBar 底部导航栏的选中状态 ;


PageView(
  /// 控制跳转翻页的控制器
  controller: _pageController,
  /// 页面滑动
  /// 这里设置 PageView 页面滑动也能
  onPageChanged: (index) {
    setState(() {
      // 更新当前的索引值
      _currentIndex = index;
    });
  },
}






四、完整代码示例




1、核心导航组件


import 'package:flutter/material.dart';

import 'package:flutter_app/pages/home_page.dart';

import 'package:flutter_app/pages/image_page.dart';

import 'package:flutter_app/pages/search_page.dart';

import 'package:flutter_app/pages/setting_page.dart';


/// 应用的主界面组件 , 整个应用的初始根节点
class MainNavigatorWidget extends StatefulWidget {
  @override
  _MainNavigatorWidgetState createState() => _MainNavigatorWidgetState();
}
/// 该类的父类 State 接受一个泛型
/// 泛型类型是 StatefulWidget 类型 TabNavigator
class _MainNavigatorWidgetState extends State<MainNavigatorWidget>
    with SingleTickerProviderStateMixin {
  /// 当前的索引值
  int _currentIndex = 0;
  /// PageView 控制器 , 用于控制 PageView
  var _pageController = PageController(
    /// 初始索引值
    initialPage: 0,
  );
  @override
  void dispose() {
    super.dispose();
    /// 销毁 PageView 控制器
    _pageController.dispose();
  }
  @override
  Widget build(BuildContext context) {
    /// 根组件
    return Scaffold(
      /// 滑动组件 , 界面的核心元素
      body: PageView(
        /// 控制跳转翻页的控制器
        controller: _pageController,
        /// 页面滑动
        /// 这里设置 PageView 页面滑动也能
        onPageChanged: (index) {
          setState(() {
            // 更新当前的索引值
            _currentIndex = index;
          });
        },
        /// Widget 组件数组 , 设置多个 Widget 组件
        /// 同一时间只显示一个页面组件
        children: [
          HomePage(), // 首页
          ImagePage(), // 图片页
          SearchPage(), // 搜索页
          SettingPage(), // 个人设置页
        ],
      ),
      /// 设置底部导航栏按钮
      bottomNavigationBar: BottomNavigationBar(
        /// 当前选中的导航索引
        currentIndex: _currentIndex,
        /// 底部导航栏的点击方法
        onTap: (index) {
          // 控制 PageView 跳转到指定的页面
          _pageController.jumpToPage(index);
          setState(() {
            // 更新当前的索引值
            _currentIndex = index;
          });
        },
        /// 设置底部的若干点击导航栏点击按钮
        /// 注意该 List<BottomNavigationBarItem> items
        /// 中的按钮顺序 , 要与 PageView 中的页面顺序必须保持一致
        /// 个数个顺序都要保持一致
        items: datas.map((data) {
          return BottomNavigationBarItem(
            /// 默认状态下的图标, 灰色
            icon: Icon(
              data.icon,
              color: Colors.grey,
            ),
            /// 选中状态下的图标, 红色
            activeIcon: Icon(
              data.icon,
              color: Colors.red,
            ),
            /// 根据当前页面是否选中 , 确定
            title: Text(
              data.title,
              style: TextStyle(
                /// 如果是选中状态 , 则设置红色
                /// 如果是非选中状态, 则设置灰色
                  color: _currentIndex == data.index ? Colors.red : Colors.grey),
            ),
          );
        }).toList(),
      ),
    );
  }
}
/// 封装导航栏的图标与文本数据
class TabData {
  /// 导航数据构造函数
  const TabData({this.index, this.title, this.icon});
  /// 导航标题
  final String title;
  /// 导航图标
  final IconData icon;
  /// 索引
  final int index;
}
/// 导航栏数据集合
const List<TabData> datas = const <TabData>[
  const TabData(index: 0, title: '首页', icon: Icons.home_outlined),
  const TabData(index: 1, title: '图片', icon: Icons.camera),
  const TabData(index: 2, title: '搜索', icon: Icons.search),
  const TabData(index: 3, title: '设置', icon: Icons.settings),
];





目录
相关文章
Flutter 小技巧之 ListView 和 PageView 的各种花式嵌套
Flutter 小技巧之 ListView 和 PageView 的各种花式嵌套 在 Flutter 中,ListView 和 PageView 是两个常用的控件,它们可以用于滑动展示大量内容的场景,且支持各种嵌套方式,本文将介绍其中的一些花式嵌套方式。
569 0
|
10月前
|
前端开发 安全 开发工具
【11】flutter进行了聊天页面的开发-增加了即时通讯聊天的整体页面和组件-切换-朋友-陌生人-vip开通详细页面-即时通讯sdk准备-直播sdk准备-即时通讯有无UI集成的区别介绍-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
【11】flutter进行了聊天页面的开发-增加了即时通讯聊天的整体页面和组件-切换-朋友-陌生人-vip开通详细页面-即时通讯sdk准备-直播sdk准备-即时通讯有无UI集成的区别介绍-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
663 90
【11】flutter进行了聊天页面的开发-增加了即时通讯聊天的整体页面和组件-切换-朋友-陌生人-vip开通详细页面-即时通讯sdk准备-直播sdk准备-即时通讯有无UI集成的区别介绍-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
|
11月前
|
Dart 前端开发
【05】flutter完成注册页面完善样式bug-增加自定义可复用组件widgets-严格规划文件和目录结构-规范入口文件-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草央千澈
【05】flutter完成注册页面完善样式bug-增加自定义可复用组件widgets-严格规划文件和目录结构-规范入口文件-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草央千澈
386 75
【05】flutter完成注册页面完善样式bug-增加自定义可复用组件widgets-严格规划文件和目录结构-规范入口文件-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草央千澈
|
11月前
|
Dart 前端开发 容器
【07】flutter完成主页-完成底部菜单栏并且做自定义组件-完整短视频仿抖音上下滑动页面-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草央千澈
【07】flutter完成主页-完成底部菜单栏并且做自定义组件-完整短视频仿抖音上下滑动页面-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草央千澈
369 18
【07】flutter完成主页-完成底部菜单栏并且做自定义组件-完整短视频仿抖音上下滑动页面-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草央千澈
|
11月前
|
缓存 前端开发 Android开发
【04】flutter补打包流程的签名过程-APP安卓调试配置-结构化项目目录-完善注册相关页面-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程
【04】flutter补打包流程的签名过程-APP安卓调试配置-结构化项目目录-完善注册相关页面-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程
505 12
【04】flutter补打包流程的签名过程-APP安卓调试配置-结构化项目目录-完善注册相关页面-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程
|
11月前
|
缓存 前端开发 IDE
【06】flutter完成注册页面-密码登录-手机短信验证-找回密码相关页面-并且实现静态跳转打包demo做演示-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草央千澈
【06】flutter完成注册页面-密码登录-手机短信验证-找回密码相关页面-并且实现静态跳转打包demo做演示-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草央千澈
300 0
【06】flutter完成注册页面-密码登录-手机短信验证-找回密码相关页面-并且实现静态跳转打包demo做演示-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草央千澈
|
Dart UED 开发者
flutter鸿蒙版本通过底部导航栏的实现熟悉架构及语法
这篇博客详细解析了一个 Flutter 应用的完整代码,实现了带有底部导航栏的功能,允许用户在不同页面之间切换。通过逐行讲解,帮助读者理解 Flutter 的结构、状态管理和组件交互。代码涵盖了从引入包、创建主入口、定义无状态和有状态组件,到构建用户界面的全过程。希望对 Flutter 开发者有所帮助。
323 3
|
Dart UED 索引
flutter鸿蒙版本通过底部导航栏的实现熟悉架构及语法
flutter鸿蒙版本通过底部导航栏的实现熟悉架构及语法
127 2
|
Dart 开发者
flutter:页面整合 (十)
本文档介绍了如何在 Flutter 应用中使用底部导航栏(`BottomNavigationBar`)和侧边栏(`Drawer`),包括简单的使用方法、属性配置、与按钮结合使用、使用图片作为图标、以及如何实现顶部导航。示例代码展示了如何创建包含多个页面的导航栏,并通过 `TabController` 控制器实现页面切换。同时,文档还提供了如何自定义导航栏样式和添加浮动操作按钮(`FloatingActionButton`)的方法。最后,整合了底部导航栏、侧边栏和顶部导航栏的完整示例代码,帮助开发者快速构建具有导航功能的 Flutter 应用界面。
187 0
|
UED
Flutter之ListView实现自动滑动到底部
Flutter之ListView实现自动滑动到底部
572 1