【Flutter】容器类组件之Scaffold、TabBar、底部导航
前言
一个完整的路由页可能会包含导航栏、抽屉菜单(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、底部导航的更多相关文章
- 微信小程序把玩(三)tabBar底部导航
原文:微信小程序把玩(三)tabBar底部导航 tabBar相对而言用的还是比较多的,但是用起来并没有难,在app.json中配置下tabBar即可,注意tabBar至少需要两个最多五个Item选项 ...
- 微信小程序tabBar底部导航 不显示问题解析
2019年十月八号 转藏: 版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明. 本文链接:https://blog.csdn.net/wy_Blo ...
- 微信小程序~TabBar底部导航切换栏
底部导航栏这个功能是非常常见的一个功能,基本上一个完成的app,都会存在一个导航栏,那么微信小程序的导航栏该怎么实现呢?经过无数的踩坑,终于实现了,好了,先看看效果图. 对于底部导航栏,小程序上给出的 ...
- 20个Flutter实例视频教程-第02节: 底部导航栏制作-2
视频地址: https://www.bilibili.com/video/av39709290?p=2 博客地址: https://jspang.com/post/flutterDemo.html#t ...
- 微信小程序自定义底部导航栏组件+跳转
微信小程序本来封装有底部导航栏,但对于想自定义样式和方法的开发者来说,这并不是很好. 参考链接:https://github.com/ljybill/miniprogram-utils/tree/ma ...
- 【Flutter学习】基本组件之BottomNavigationBar底部导航栏
一,概述 BottomNavigationBar即是底部导航栏控件,显示在页面底部的设计控件,用于在试图切换,底部导航栏包含多个标签.图标或者两者搭配的形式,简而言之提供了顶级视图之间的快速导航. 二 ...
- 【Flutter学习】基本组件之TabBar顶部导航
一,概述 TabBar,是材料设计(Material design)中很常用的一种横向标签页.在Android原生开发中,我们常用ViewPage或者一些常用的标签页开源库,来实现并行界面的横向滑动展 ...
- Flutter——BottomNavigationBar组件(底部导航栏组件)
BottomNavigationBar常用的属性: 属性名 说明 items List<BottomNavigationBarItem> 底部导航条按钮集合 iconSize icon c ...
- Flutter学习笔记(17)--顶部导航TabBar、TabBarView、DefaultTabController
如需转载,请注明出处:Flutter学习笔记(17)--顶部导航TabBar.TabBarView.DefaultTabController 上一篇我们说了BottmNavigationBar底部导航 ...
随机推荐
- hashmap底层:jdk1.8前后的改变
将hashmap和currenthashmap放一块进行比较,是因为二者的结构相差不多,只不过后者是线程安全的. 首先说hashmap,在jdk1.8之前,hashmap的存储结构是数组+链表的形式, ...
- Layui事件监听(表单和数据表格)
一.表单的事件监听 先介绍一下几个属性的用法 1.lay-filter 事件过滤器 相当于选择器,layui的专属选择器 2.lay-verify 验证属性 属性值可以是 :required必填项, ...
- Object not found! The requested URL was not found on this server.... 报错解决方案
服务器(centos6.5) lnmp 报错如下 Object not found! The requested URL was not found on this server. The link ...
- vscode 编辑python文件
1 安装python 自动姿势 Chinese # 换成中文 path Autocomplete 路径自动补全 Vetur vue文件补全 配置文件 首选项-设置 应用程序 在 seyying.jso ...
- Jmeter连接redis
介绍:现在有很多数据不是存储在数据库而是存储在Redis中 Redis数据库存储数据环境 不用每次都去数据库读取数据 可以有效的优化服务器性能. 下面介绍使用jmeter如何读取redis 一.首先创 ...
- Jmeter二次开发——基于Java请求
简述 这近几年,越来越多非http的协议需要进行性能测试,包括不仅限于各类rpc.mq.缓存等.对于这些协议,市面上可能没有现成的工具可以直接使用,这个时候,我们可以自己动手,通过编写相应的JavaS ...
- 安利一波这12个IDEA插件,太香了!
这里补充一下常用的插件, 非常值得安利一波! 1.日晒主题 Solarized Themes 推荐指数:☆☆☆☆☆ 推荐理由:日晒主题本身是为vim定制的.后来移植到ide 非常酷!配色非常耐看. ...
- vue API 知识点(4) --- 指令、特殊 attribute 、内置组件
一.指令 1.v-text <span v-text="msg"></span> <!-- 两种写法是一样的 --> <span>{ ...
- EF Code First生成的数据表去复数(去掉数据表最后面那个s) 和 EF decimal 小数位的保留
modelBuilder.Conventions.Remove<System.Data.Entity.ModelConfiguration.Conventions.PluralizingTabl ...
- MySQL忘记密码了怎么解决
前言:在不考虑到原来用户对关联数据库的授权问题的情况下,有以下三种思路解决 #1.登录状态下修改 说明:在登录状态的话,直接使用命令修改密码就行了 mysql> use mysql; mysql ...