Flutter 底部导航——BottomNavigationBar

前言

Google推出flutter这样一个新的高性能跨平台(Android,ios)快速开发框架之后,被业界许多开发者所关注。我在接触了flutter之后发现这个确实是一个好东西,好东西当然要和大家分享,对吧。

今天要跟大家分享的是底部导航功能的实现。我认为flutter的就是在传达一种最简设计,一个部件只关注它本身,达到低耦合高内聚。所以本文讲解底部导航将只关注该功能的实现,并对布局思路进行介绍。

你将学到什么

  • 如何将部件拆分
  • 如何构建flutter布局
  • 如何创建底部导航

首先让大家看看效果。

这是一个最简单的底部导航案例,我不希望引入过多其他东西,把初学者的脑子搞得很乱(这也是我在学习中所遇到的)。

建立布局

第一步:绘制布局视图

将布局分解为基本元素:

  • 页面是由哪些元素构成的
  • 哪些控件会因为用户的交互而发生变化,哪些不会

在这个应用中我们期望能够通过点击底部导航栏就能切换上面的整个页面。这个行为触发了页面的刷新。

这里我们需要思考一个问题,刷新的范围在哪里?

用过手机app的同学都知道,我们可以点击底部导航栏,底部是不会刷新的,而刷新的只有上面部分。所以我们可以把整个页面拆成两部分。

第一个部分是橘色框里的页面部分,第二个部分是我们底部的导航器部分。而导航器是一直不变的,所以导航器应该是在它们之中处于父级widget层次。

第二步:开始构造底部导航

1class BottomNavigationWidget extends StatefulWidget { 2 @override 3 State<StatefulWidget> createState() => BottomNavigationWidgetState(); 4} 5 6class BottomNavigationWidgetState extends State<BottomNavigationWidget> { 7 final _bottomNavigationColor = Colors.blue; 8 int _currentIndex = 0; 9 10 @override 11 Widget build(BuildContext context) { 12 return Scaffold( 13 bottomNavigationBar: BottomNavigationBar( 14 items: [ 15 BottomNavigationBarItem( 16 icon: Icon( 17 Icons.home, 18 color: _bottomNavigationColor, 19 ), 20 title: Text( 21 'HOME', 22 style: TextStyle(color: _bottomNavigationColor), 23 )), 24 BottomNavigationBarItem( 25 icon: Icon( 26 Icons.email, 27 color: _bottomNavigationColor, 28 ), 29 title: Text( 30 'Email', 31 style: TextStyle(color: _bottomNavigationColor), 32 )), 33 BottomNavigationBarItem( 34 icon: Icon( 35 Icons.pages, 36 color: _bottomNavigationColor, 37 ), 38 title: Text( 39 'PAGES', 40 style: TextStyle(color: _bottomNavigationColor), 41 )), 42 BottomNavigationBarItem( 43 icon: Icon( 44 Icons.airplay, 45 color: _bottomNavigationColor, 46 ), 47 title: Text( 48 'AIRPLAY', 49 style: TextStyle(color: _bottomNavigationColor), 50 )), 51 ], 52 currentIndex: _currentIndex, 53 onTap: (int index) { 54 setState(() { 55 _currentIndex = index; 56 }); 57 }, 58 ), 59 ); 60 } 61}

我们这里使用了Scaffold布局,它默认提供了一个bottomNavigationBar的属性,我们在这里给它一个BottomNavigationBar,并在这个BottomNavigationBar中放了四个BottomNavigationBarItem(一下简称item)。每个item就是底部的一个导航按钮。

BottomNavigationBar的items是一个数组,那么就会存在下标。BottomNavigationBar为我们提供了一个currentIndex属性,默认是0,我们进去看看这个方法。

1 /// The index into [items] of the current active item. 2 final int currentIndex;

currentIndex代表了当前再items中被选中的index。

BottomNavigationBar还提供了一个onTap方法。我们再看看这个方法。

1 /// The callback that is called when a item is tapped. 2 /// The widget creating the bottom navigation bar needs to keep track of the 3 /// current index and call `setState` to rebuild it with the newly provided 4 /// index. 5 final ValueChanged<int> onTap;

当底部导航的一个item被点击时,它会调用此方法,并传入当前item的index值,这样就能改变焦点到当前的index上的item了。

我们来看看效果:

创建切换页面

然后我们需要分别创建四个页面,对映四个item,由于四个页面极为相似这里只放一个。建议大家对这四个页面分别创建一个dart文件。

1import 'package:flutter/material.dart'; 2 3class HomeScreen extends StatefulWidget { 4 @override 5 State<StatefulWidget> createState() => HomeScreenState(); 6} 7 8class HomeScreenState extends State<HomeScreen> { 9 @override 10 Widget build(BuildContext context) { 11 return Scaffold( 12 appBar: AppBar( 13 title: Text('HOME'), 14 ), 15 ); 16 } 17}

每个页面都是一个Scaffold布局,有一个appBar。

将页面显示在界面上

我们再回到底部导航这个控件中。 由于我们是通过currentIndex这个变量来控制跳转的,页面要想同步也必须依赖于这个变量。这里我们使用一个List<Widget>来与items对应。

1List<Widget> pages = List<Widget>(); 2 final _bottomNavigationBarItemColor = Colors.teal; 3 int _currentIndex = 0; 4 5 @override 6 void initState() { 7 pages 8 ..add(HomeScreen()) 9 ..add(EmailScreen()) 10 ..add(AlarmsScreen()) 11 ..add(ProfileScreen()); 12 }

然后让我们的BottomNavigation的Scaffold布局中body部分为List中的页面。

body: pages[_bottomNavigationIndex],

我们让_currentIndex来控制我们到底再body这个位置上显示哪个页面。这样就能够通过Tap我们的bottomNavigationItem来达到控制页面跳转的作用啦。

相关链接:

完整代码: https://github.com/Vadaski/Vadaski-flutter_note_book/tree/master/mecury_project/example/flutter_bottomnavigationbar

Youtube教学视频: https://www.youtube.com/watch?v=iYDaC2ESCkg&t=1221s

bilibili教学视频: https://www.bilibili.com/video/av28014369

之后将持续分享一些flutter经验,有任何问题的话欢迎回复,我会很快更新的!

点赞
收藏

评论区

加载中...

相关推荐

MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1

文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s

Oracle 分组与拼接字符串同时使用

SELECTT.,ROWNUMIDFROM(SELECTT.EMPLID,T.NAME,T.BU,T.REALDEPART,T.FORMATDATE,SUM(T.S0)S0,MAX(UPDATETIME)CREATETIME,LISTAGG(TOCHAR(

皕杰报表之UUID

​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为

手写Java HashMap源码

HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22

【Flutter实战】初识Flutter

1.2初识Flutter1.2.1Flutter简介Flutter是Google推出并开源的移动应用开发框架,主打跨平台、高保真、高性能。开发者可以通过Dart语言开发App,一套代码同时运行在iOS和Android平台。Flutter提供了丰富的组件、接口,开发者可以很快地为Flutter添加native扩展。同时Flu

Flutter 不一样的跨平台解决方案

本文主要介绍Flutter相关的东西,包括Fuchsia、Dart、Flutter特性、安装以及整体架构等内容。1\.简介Flutter作为谷歌最近推出的跨平台开发框架,一经推出便吸引了不少注意。关于Flutter,目前我们知道它是一个跨平台开发框架。但是它本身并不止于此,例如Fuchsia、Dart等,我们也都需要去了解。