美文网首页雨竹
Flutter基础(六)Material组件之BottomNav

Flutter基础(六)Material组件之BottomNav

作者: 乘香墨影 | 来源:发表于2019-06-06 10:04 被阅读32次

    今日早报:

           波场TRON创始人孙宇晨砸了456万美元,成功拍卖了和巴菲特吃午饭的机会;

            据央视新闻官方微博消息,工信部今日向中国电信、中国移动、中国联通、中国广电发放5G商用牌照。

    前言

    在上一篇 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的值就可以切换选项卡了。实现的效果如下所示,可以通过点击选项卡来切换界面。

    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。运行效果如下所示,可以通过滑动界面和点击选项卡来切换界面。

    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,可以很轻松的设置用户的姓名、邮箱、用户图片等。效果如下图所示:

    总结

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

    原文:http://liuwangshu.cn/flutter/primer/6-material-components-2.html

    后续还有更多精彩文章,大家请关注我的微信公众号

    相关文章

      网友评论

        本文标题:Flutter基础(六)Material组件之BottomNav

        本文链接:https://www.haomeiwen.com/subject/uxlyxctx.html