前言

一个完整的路由页可能会包含导航栏、抽屉菜单(Drawer)以及底部Tab导航菜单等。Flutter Material组件库提供了一些现成的组件来减少开发任务。Scaffold是一个路由页的骨架,使用它可以很容易地拼装出一个完整的页面。

接口描述

AppBar是一个Material风格的导航栏,通过它可以设置导航栏标题、导航栏菜单、导航栏底部的Tab标题等。

AppBar({
Key key,
// 导航栏最左侧的widget,常见为抽屉菜单按钮或返回按钮。可手动来设置这一项
this.leading,
// 如果leading为null,是否自动实现默认的leading按钮
this.automaticallyImplyLeading = true,
// 页面标题
this.title,
// 导航栏右侧菜单
this.actions,
this.flexibleSpace,
// 导航栏底部菜单,通常为Tab按钮组
this.bottom,
// 导航栏阴影
this.elevation,
this.shape,
this.backgroundColor,
this.brightness,
this.iconTheme,
this.actionsIconTheme,
this.textTheme,
this.primary = true,
// 标题时候居中
this.centerTitle,
this.titleSpacing = NavigationToolbar.kMiddleSpacing,
this.toolbarOpacity = 1.0,
this.bottomOpacity = 1.0,
}) : assert(automaticallyImplyLeading != null),
assert(elevation == null || elevation >= 0.0),
assert(primary != null),
assert(titleSpacing != null),
assert(toolbarOpacity != null),
assert(bottomOpacity != null),
preferredSize = Size.fromHeight(kToolbarHeight + (bottom?.preferredSize?.height ?? 0.0)),
super(key: key);

Material组件库中提供了一个TabBar组件,它可以快速生成Tab菜单。

const TabBar({
Key key,
@required this.tabs,
this.controller,
this.isScrollable = false,
this.indicatorColor,
this.indicatorWeight = 2.0,
this.indicatorPadding = EdgeInsets.zero,
this.indicator,
this.indicatorSize,
this.labelColor,
this.labelStyle,
this.labelPadding,
this.unselectedLabelColor,
this.unselectedLabelStyle,
this.dragStartBehavior = DragStartBehavior.start,
this.onTap,
}) : assert(tabs != null),
assert(isScrollable != null),
assert(dragStartBehavior != null),
assert(indicator != null || (indicatorWeight != null && indicatorWeight > 0.0)),
assert(indicator != null || (indicatorPadding != null)),
super(key: key);

Material库提供了一个TabBarView组件,通过它不仅可以轻松的实现Tab页,而且可以非常容易的配合TabBar来实现同步切换和滑动状态同步.

const TabBarView({
Key key,
@required this.children,
this.controller,
this.physics,
this.dragStartBehavior = DragStartBehavior.start,
}) : assert(children != null),
assert(dragStartBehavior != null),
super(key: key);

无论是点击导航栏Tab菜单还是在页面上左右滑动,Tab页面都会切换,并且Tab菜单的状态和Tab页面始终保持同步!那它们是如何实现同步的呢?因为TabBar和TabBarView的controller是同一个!正是如此,TabBar和TabBarView正是通过同一个controller来实现菜单切换和滑动状态同步的。

代码示例

// Scaffold、TabBar、底部导航

import 'package:flutter/material.dart';

class ScaffoldTest extends StatefulWidget {
@override
_ScaffoldTestState createState() => _ScaffoldTestState();
} class _ScaffoldTestState extends State<ScaffoldTest> with SingleTickerProviderStateMixin{
int _selectedIndex = 2;
TabController _tabController;
List tabs = ['会话', '系统']; @override
void initState() {
print('初始化了数据!');
super.initState();
// 创建Controller
_tabController = TabController(length: tabs.length, vsync: this);
} @override
Widget build(BuildContext context) {
return Scaffold(
// AppBar是一个Material风格的导航栏,通过它可以设置导航栏标题、导航栏菜单、导航栏底部的Tab标题等
appBar: AppBar( // 导航栏最左侧的widget
leading: Builder(builder: (context) {
return IconButton(
// 自定义图标
icon: Icon(Icons.dashboard, color: Colors.red,),
onPressed: () {
// 打开抽屉菜单
Scaffold.of(context).openDrawer();
},
);
}), // 导航栏标题
title: Text('Test App'), // 导航栏右侧菜单
actions: <Widget>[
IconButton(icon: Icon(Icons.share),onPressed: () {},),
], // Tab菜单
bottom: TabBar(
controller: this._tabController,
// isScrollable: true,
tabs: <Widget>[
Tab(text: tabs[0]),
Tab(text: tabs[1]),
],
), ), // 抽屉
drawer: MyDrawer(), body: TabBarView(
controller: this._tabController,
children: <Widget>[
Container(
alignment: Alignment.center,
child: Text(tabs[0], textScaleFactor: 10),
),
Container(
alignment: Alignment.center,
child: Text(tabs[1], textScaleFactor: 10),
),
],
), // 底部导航
bottomNavigationBar: BottomNavigationBar(
items: <BottomNavigationBarItem>[
BottomNavigationBarItem(icon: Icon(Icons.home), title: Text('首页'), backgroundColor: Colors.blue,),
BottomNavigationBarItem(icon: Icon(Icons.system_update_alt), title: Text('数据'), backgroundColor: Colors.blue,),
BottomNavigationBarItem(icon: Icon(Icons.notifications_active), title: Text('通知'), backgroundColor: Colors.blue,),
BottomNavigationBarItem(icon: Icon(Icons.settings), title: Text('设置'), backgroundColor: Colors.blue,),
],
currentIndex: _selectedIndex,
fixedColor: Colors.red,
onTap: _onItemTapped,
), // 悬浮按钮
floatingActionButton: FloatingActionButton(
child: Icon(Icons.add),
onPressed: _onAdd,
backgroundColor: Colors.blue,
),
// 设置悬浮按钮的位置为底部导航栏的正中间
// floatingActionButtonLocation: FloatingActionButtonLocation.centerDocked, // 增加打洞按钮
// bottomNavigationBar: BottomAppBar(
// color: Colors.green,
// // 底部导航栏打一个圆形的洞
// shape: CircularNotchedRectangle(),
// child: Row(
// children: <Widget>[
// IconButton(icon: Icon(Icons.home),),
// // 中间位置空出
// SizedBox(),
// IconButton(icon: Icon(Icons.business),),
// ],
// mainAxisAlignment: MainAxisAlignment.spaceAround,
// ),
// ), );
} void _onItemTapped(int index) {
setState(() {
_selectedIndex = index;
});
} void _onAdd() {
print('_onAdd');
} } class MyDrawer extends StatelessWidget { MyDrawer({Key key,}) : super(key:key); @override
Widget build(BuildContext context) {
return Drawer(
child: MediaQuery.removePadding(
context: context,
// 移除抽屉菜单顶部默认留白
removeTop: true,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[ Padding(
padding: const EdgeInsets.only(top: 38.0),
child: Row(
children: <Widget>[
Padding(
padding: const EdgeInsets.symmetric(horizontal: 16.0),
child: ClipOval(
child: Image.asset('assets/images/avatar.png', width: 80,),
),
),
Text('parzulpan',style: TextStyle(fontWeight: FontWeight.bold),)
],
),
), Expanded(
child: ListView(
children: <Widget>[
ListTile(
leading: const Icon(Icons.add),
title: const Text('增加账户'),
),
ListTile(
leading: const Icon(Icons.info),
title: const Text('账户管理'),
), ],
),
)
],
)
),
);
} }

总结

暂无

【Flutter】容器类组件之Scaffold、TabBar、底部导航的更多相关文章

  1. 微信小程序把玩(三)tabBar底部导航

    原文:微信小程序把玩(三)tabBar底部导航 tabBar相对而言用的还是比较多的,但是用起来并没有难,在app.json中配置下tabBar即可,注意tabBar至少需要两个最多五个Item选项 ...

  2. 微信小程序tabBar底部导航 不显示问题解析

    2019年十月八号 转藏: 版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明. 本文链接:https://blog.csdn.net/wy_Blo ...

  3. 微信小程序~TabBar底部导航切换栏

    底部导航栏这个功能是非常常见的一个功能,基本上一个完成的app,都会存在一个导航栏,那么微信小程序的导航栏该怎么实现呢?经过无数的踩坑,终于实现了,好了,先看看效果图. 对于底部导航栏,小程序上给出的 ...

  4. 20个Flutter实例视频教程-第02节: 底部导航栏制作-2

    视频地址: https://www.bilibili.com/video/av39709290?p=2 博客地址: https://jspang.com/post/flutterDemo.html#t ...

  5. 微信小程序自定义底部导航栏组件+跳转

    微信小程序本来封装有底部导航栏,但对于想自定义样式和方法的开发者来说,这并不是很好. 参考链接:https://github.com/ljybill/miniprogram-utils/tree/ma ...

  6. 【Flutter学习】基本组件之BottomNavigationBar底部导航栏

    一,概述 BottomNavigationBar即是底部导航栏控件,显示在页面底部的设计控件,用于在试图切换,底部导航栏包含多个标签.图标或者两者搭配的形式,简而言之提供了顶级视图之间的快速导航. 二 ...

  7. 【Flutter学习】基本组件之TabBar顶部导航

    一,概述 TabBar,是材料设计(Material design)中很常用的一种横向标签页.在Android原生开发中,我们常用ViewPage或者一些常用的标签页开源库,来实现并行界面的横向滑动展 ...

  8. Flutter——BottomNavigationBar组件(底部导航栏组件)

    BottomNavigationBar常用的属性: 属性名 说明 items List<BottomNavigationBarItem> 底部导航条按钮集合 iconSize icon c ...

  9. Flutter学习笔记(17)--顶部导航TabBar、TabBarView、DefaultTabController

    如需转载,请注明出处:Flutter学习笔记(17)--顶部导航TabBar.TabBarView.DefaultTabController 上一篇我们说了BottmNavigationBar底部导航 ...

随机推荐

  1. CSP-S 2019 Solution

    Day1-T1 格雷码(code) 格雷码是一种特殊的 \(n\) 位二进制串排列法,要求相邻的两个二进制串恰好有一位不同,环状相邻. 生成方法: \(1\) 位格雷码由两个 \(1\) 位的二进制串 ...

  2. BJOI2015 隐身术

    落谷. Description 给你两个串 \(A.B\).询问 \(B\) 中有多少个非空子串和 \(A\) 的编辑距离不超过 \(K\). Solution 发现 \(K \le 5\),考虑可以 ...

  3. 题解-Enemy is weak

    Enemy is weak 求序列 \(a\{n\}\) 中的三元逆序对数量. 数据范围:\(3\le n\le 1e6\). 这题真是一道又好又水的题,可是我看别人的题解做法真是玄学难懂,于是蒟蒻要 ...

  4. Jmeter(10)逻辑控制器

    逻辑控制器可以控制采样器的执行顺序,所以控制器需要和采样器一起使用 Jmeter中的逻辑控制器分为两类 1.控制测试计划执行过程中节点的逻辑顺序,如循环控制器.If控制器 2.对测试计划中的脚本进行分 ...

  5. Python Windows开发环境搭建

    一.下载python安装包 python官网地址:https://www.python.org/,下载windows平台包并安装 二.在Windows设置环境变量 计算机右键,选择属性,在高级系统设置 ...

  6. 女朋友突然问我DNS是个啥....

    女朋友突然问我DNS是个啥.... 今天晚上我正在床上躺着刷手机,然后我女朋友突然说她的电脑坏了.说连着WIFi上不了网,让我给她看一下.(这就是有个程序员男朋友的好处) 然后我拿到电脑看了一下发现访 ...

  7. 用列表+for循环生成乘法口诀表

    1 # 结合一下列表生成, 准备设计乘法表 2 # numlist = [1,2,3,4,5] 3 # [pow(i,3) for i in numlist] 4 # ## [1, 8, 27, 64 ...

  8. C#数据结构-线索化二叉树

    为什么线索化二叉树? 对于二叉树的遍历,我们知道每个节点的前驱与后继,但是这是建立在遍历的基础上,否则我们只知道后续的左右子树.现在我们充分利用二叉树左右子树的空节点,分别指向当前节点的前驱.后继,便 ...

  9. 个人微信公众号搭建Python实现 -个人公众号搭建-永久素材管理(14.3.5)

    @ 目录 1.说明 2.上传素材 3.获取素材列表 关于作者 1.说明 个人微信公众号开发的功能有限,因为很多权限没有,但支持上传永久素材,具体查看微信公众号文档 这里的请求都要将本地IP地址放到微信 ...

  10. linux操作系统及常用命令

    GUN:GUN is Not UnixGPL:General Public License.通用公共许可证,版权 Copyright,Copyleft 开源协议LGPL:lesserGPLv2GPLv ...