前言

一个完整的路由页可能会包含导航栏、抽屉菜单(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. CSS基础-边框

    border border-top设置上边界 border-bottom / border-left / border-right 同理 可以为每一条边设置 : border-top-width宽度 ...

  2. 如何实现OSM地图本地发布并自定义配图

    目录 1.缘起 2.准备环境 2.1.安装linux系统 2.2.安装docker 2.3.安装Docker Compose 2.4.安装git 3.发布地图 3.1.拉取代码 3.2.测试网络 3. ...

  3. CF1406E 【Deleting Numbers】

    蒟蒻语 蒟蒻这次 \(CF\) 又双叒叕掉分了,\(C\) 都没有调出来. 还好再最后 \(10\) 秒钟调了下 \(E\) 块长 (块长 \(100\) => \(98\)),才没有掉得那么惨 ...

  4. [JDK8]Map接口与Dictionary抽象类

    package java.util; 一.Map接口 接口定义 public interface Map<K,V> Map是存放键值对的数据结构.map中没有重复的key,每个key最多只 ...

  5. STL——容器(List)List 的数据元素插入和删除操作

    push_back(elem); //在容器尾部加入一个元素 1 #include <iostream> 2 #include <list> 3 4 using namespa ...

  6. Bootstrap 的基本使用

    一.Bootstrap简介 Bootstrap 是目前受欢迎的前端框架之一,是基于HTML,CSS,JavaScript的,它简洁灵活,使web开发更加快捷 中文官网:http://www.bootc ...

  7. 自顶向下redis4.0(4)时间事件与expire

    redis4.0的时间事件与expire 目录 redis4.0的时间事件与expire 简介 正文 时间事件注册 时间事件触发 expire命令 删除过期键值 被动删除 主动删除/定期删除 参考文献 ...

  8. UML—20—002

    博客班级 < https://edu.cnblogs.com/campus/fzzcxy/2018SE1> 作业要求 <https://edu.cnblogs.com/campus/ ...

  9. 初始Node

    node是什么? ​ 一句话: 服务器 什么是服务器: ​ 一句话: 客户端访问 并且能够响应 为什么: ​ 一句话: 执行效率高 #安装 #控制台 切换磁盘: e: 改变目录: cd 目录 cd.. ...

  10. sqlmap进阶篇—POST注入三种方法

    测试是否存在post注入 第一种方法 直接加--form让它自动加载表单 第二种方法 把form表单里面提交的内容复制出来,放到data中跑 第三种方法 先用burp suite抓包,把包的内容存到本 ...