宁泽林_NiZerin - 互联网技术博客

  • PHP
  • Go
  • Java
  • Rust
  • Python
  • 交流群
  • 关于我
  • 留言版
  1. 首页
  2. Flutter
  3. 正文

Flutter 基础(六)Material 组件之 BottomNavigationBar、TabBar、Drawer

2019年7月1日 2256点热度 0人点赞 0条评论
图片

前言

在上一篇 Flutter 基础(五)Material 组件最佳入门(前篇)中,我介绍了 Material 组件的 MaterialApp、Scaffold、AppBar,这篇文章接着介绍 Material 组件中的 BottomNavigationBar、TabBar、Drawer。

1.BottomNavigationBar

BottomNavigationBar 是底部的导航栏,用于在 3 到 5 个的少量视图中进行选择。一般情况下,导航栏的选项卡由文本标签、图标或两者结合的形式组成。
底部导航栏通常与 javaScaffold 结合使用,它会作为 Scaffold.bottomNavigationBar 参数。


import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
 static const String _title = 'Flutter Code Sample';
 @override
 Widget build(BuildContext context) {
 return MaterialApp(
 home: MyStatefulWidget(),
 );
 }
}
class MyStatefulWidget extends StatefulWidget {
 MyStatefulWidget({Key key}) : super(key: key);
 @override
 _MyStatefulWidgetState createState() => _MyStatefulWidgetState();//1
}
class _MyStatefulWidgetState extends State<MyStatefulWidget> {
 int _selectedIndex = 0;
 static const List<Widget> _widget = <Widget>[
 Text(
 'Index 0:首页',
 ),
 Text(
 'Index 1: 通讯录',
 ),
 Text(
 'Index 2: 设置',
 ),
 ];
 @override
 Widget build(BuildContext context) {
 return Scaffold(
 appBar: AppBar(
 title: Text('BottomNavigationBar示例'),
 ),
 body: Center(
 child: _widget.elementAt(_selectedIndex),
 ),
 bottomNavigationBar: BottomNavigationBar(
 items: const <BottomNavigationBarItem>[
 BottomNavigationBarItem(
 icon: Icon(Icons.home),
 title: Text('首页'),
 ),
 BottomNavigationBarItem(
 icon: Icon(Icons.contacts),
 title: Text('通讯录'),
 ),
 BottomNavigationBarItem(
 icon: Icon(Icons.build),
 title: Text('设置'),
 ),
 ],
 currentIndex: _selectedIndex,
 selectedItemColor: Colors.amber,
 onTap: _onItemTapped, //2
 ),
 );
 }
 void _onItemTapped(int index) {
 setState(() {
 _selectedIndex = index;
 });
 }
}

由于使用的 Widget 需要在 Widget 的生命周期中改变状态,因此 MyStatefulWidget 继承了 StatefulWidget。注释 1 处的 createState 方法会为此 Widget 创建可变状态。注释 2 处的 onTap 属性会在点击其中一个选项卡时调用,它的值由_onItemTapped 方法定义,在这个方法中设置当前的索引赋值给_selectedIndex,这样通过_selectedIndex 的值就可以切换选项卡了。实现的效果如下所示,可以通过点击选项卡来切换界面。

VYUinA.png

2.TabBar

TabBar 用于显示水平的选项卡,和 Android 中的 TabLayout 类似。TabBar 通常需要配合 TabBarView 和 TabController。其中 TabBarView 用于显示与当前所选的选项卡对应的 Widget 视图;TabController 顾名思义就是 TabBarView 和 TabBar 的控制器,是这两个 Widget 的桥梁。实现 TabController 有两种方式,一种是用系统的 DefaultTabController,另一种是自定义 TabController。

2.1 使用 DefaultTabController

DefaultTabController 这种方式方便快捷,直接新建一个 DefaultTabController 就可以了。


import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
 @override
 Widget build(BuildContext context) {
 return MaterialApp(
 home: MyTabController(),
 );
 }
}
class MyTabController extends StatelessWidget {
 @override
 Widget build(BuildContext context) {
 return DefaultTabController(
 length: 3,
 child: Scaffold(
 appBar: AppBar(
 title: Text('DefaultTabController示例'),
 bottom: TabBar(
 tabs: <Widget>[
 Tab(
 text: '热点',
 ),
 Tab(
 text: '体育',
 ),
 Tab(
 text: '科技',
 ),
 ],
 ),
 ),
 body: TabBarView(
 children: <Widget>[
 Center(child: Text('热点')),
 Center(child: Text('体育')),
 Center(child: Text('科技')),
 ],
 ),
 ),
 );
 }
}

2.2 自定义 TabController

如果想要切换动画或者监听切换的交互,可以自定义 TabController,需要实现 SingleTickerProviderStateMixin。


import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
 @override
 Widget build(BuildContext context) {
 return MaterialApp(
 home: MyStatefulWidget(),
 );
 }
}
class MyStatefulWidget extends StatefulWidget {
 MyStatefulWidget({Key key}) : super(key: key);
 @override
 _MyStatefulWidgetState createState() => _MyStatefulWidgetState();
}
class _MyStatefulWidgetState extends State<MyStatefulWidget>
 with SingleTickerProviderStateMixin {
 TabController _tabController;
 void initState() {
 super.initState();
 _tabController = TabController(vsync: this, length: 3);
 }
 @override
 Widget build(BuildContext context) {
 return Scaffold(
 appBar: AppBar(
 title: Text('自定义TabController'),
 bottom: TabBar(
 tabs: <Widget>[
 Tab(
 text: '热点',
 ),
 Tab(
 text: '体育',
 ),
 Tab(
 text: '科技',
 ),
 ],
 controller: _tabController,//1
 ),
 ),
 body: TabBarView(
 controller: _tabController,
 children: <Widget>[
 Center(child: Text('热点')),
 Center(child: Text('体育')),
 Center(child: Text('科技')),
 ],
 ),
 );
 }
 @override
 void dispose() {
 _tabController.dispose();
 super.dispose();
 }
}

和第一种使用 DefaultTabController 有两点不同,一个是使用了 StatefulWidget,另一个是在注释 1 处将 TabBar 的 controller 设置为新建的 TabController。运行效果如下所示,可以通过滑动界面和点击选项卡来切换界面。

VNYY3F.png

3.Drawer

Drawer 就是抽屉,可以实现拉出推入的效果,和 Android 中的 DrawerLayout 类似。Drawer 通常与 Scaffold.drawer 属性一起使用,抽屉的子项通常是 ListView,其第一个子项是头部,头部主要有两个 Widget 可以实现:

  • DrawerHeader: 展示基本的信息
  • UserAccountsDrawerHeader: 展示用户头像、用户名、Email 等信息。

    import 'package:flutter/material.dart';
    void main() => runApp(MyApp());
    class MyApp extends StatelessWidget {
     static const String _title = 'Flutter Code Sample';
     @override
     Widget build(BuildContext context) {
     return MaterialApp(
     home: MyStatefulWidget(),
     );
     }
    }
    class MyStatefulWidget extends StatefulWidget {
     MyStatefulWidget({Key key}) : super(key: key);
     @override
     _DrawerState createState() => _DrawerState();
    }
    class _DrawerState extends State<MyStatefulWidget> {
     @override
     Widget build(BuildContext context) {
     return Scaffold(
     appBar: AppBar(
     title: Text('Drawer例子'),
     ),
     drawer: _drawer,
     );
     }
     get _drawer => Drawer(
     child: ListView(//1
     padding: EdgeInsets.zero,
     children: <Widget>[
     UserAccountsDrawerHeader(
     accountName: Text('刘望舒'),
     accountEmail: Text('liuwangshu.gmail.com'),
     currentAccountPicture: CircleAvatar(
     child: Text('X'),
     ),
     ),
     ListTile(
     leading: Icon(Icons.local_post_office),
     title: Text('邮件'),
     ),
     ListTile(
     leading: Icon(Icons.settings),
     title: Text('设置'),
     )
     ],
     ),
     );
    }

跟以往例子不同的是,由于 drawer 属性的代码比较多,为了提高可读性,我将 drawer 属性的值抽取出来,通过 getter 的形式进行获取。注释 1 处可以看出 Drawer 的子项为 ListView,ListView 的通过 ListTile 来显示每一个列表项。注释 2 使用的是 UserAccountsDrawerHeader,可以很轻松的设置用户的姓名、邮箱、用户图片等。效果如下图所示:

VU8Nss.png

总结

加上上一篇文章,我已经介绍了 Material 组件中应用程序结构和导航分类中的大部分 Widget,另外 Material 组件所包含的其他的 Widget,本系列就不介绍了,想要了解的可以查看文档:https://flutter.dev/docs/development/ui/wi...

本作品采用 知识共享署名 4.0 国际许可协议 进行许可
标签: flutter
最后更新:2019年7月1日

NiZerin

博主已经躺平了,后面很少会更新博客。

打赏 点赞
< 上一篇
下一篇 >

文章评论

razz evil exclaim smile redface biggrin eek confused idea lol mad twisted rolleyes wink cool arrow neutral cry mrgreen drooling persevering
取消回复

分类
  • Angular
  • CSS3
  • docker
  • Flutter
  • git
  • Go
  • H5
  • Java
  • JavaScript
  • Laravel
  • linux
  • Node.js
  • PHP
  • Python
  • React
  • redis
  • Vue.js
  • windows
  • WordPress
  • 交流
  • 小程序
  • 工具
  • 网站公告
标签聚合
go laravel wordpress vue php flutter translations javascript
友情链接
  • PHP函数字典
  • 宝塔运维特惠
  • 科学上网
  • 阿里云特惠

COPYRIGHT © 2021 nizer.in. ALL RIGHTS RESERVED.

Theme Kratos Made By Seaton Jiang