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

本文首发于公众号「后厂村码农」html

ReactNative入门系列 React Native组件 Flutter基础系列前端

前言

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

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的值就能够切换选项卡了。实现的效果以下所示,能够经过点击选项卡来切换界面。 app

VYUinA.png

2.TabBar

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

2.1 使用DefaultTabController

DefaultTabController这种方式方便快捷,直接新建一个DefaultTabController就能够了。ide

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。post

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能够实现:ui

  • 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,本系列就不介绍了,想要了解的能够查看文档:flutter.dev/docs/develo…


这里不只分享大前端、Android、Java等技术,还有程序员成长类文章。
相关文章
相关标签/搜索