zoukankan      html  css  js  c++  java
  • 【Flutter学习】基本组件之TabBar顶部导航

    一,概述

      TabBar,是材料设计(Material design)中很常用的一种横向标签页。在Android原生开发中,我们常用ViewPage或者一些常用的标签页开源库,来实现并行界面的横向滑动展示,在iOS原生开发中我们可以基于UICollectionView/UIButton来封装实现这一功能,在Flutter的世界中,TabBar是被定义在Material Component中,所以他的使用需要在MaterialApp中。通常,我们会在AppBar的底部部分结合TabBarView来使用TabBar。
        


    二,Tab关键元素

    • TabController
      这是Tab页的控制器,用于定义Tab标签和内容页的坐标,还可配置标签页的切换动画效果等。
      TabController一般放入有状态控件中使用,以适应标签页数量和内容有动态变化的场景,如果标签页在APP中是静态固定的格局,则可以在无状态控件中加入简易版的DefaultTabController以提高运行效率,毕竟无状态控件要比有状态控件更省资源,运行效率更快。
    • TabBar
      Tab页的Title控件,切换Tab页的入口,一般放到AppBar控件下使用,内部有*Title属性。其子元素按水平横向排列布局,如果需要纵向排列,请使用ColumnListView控件包装一下。子元素为Tab类型的数组
    • TabBarView
      Tab页的内容容器,其内放置Tab页的主体内容。子元素可以是多个各种类型的控件。

    三,构造函数  

    • TabController
      • DefalutTabController
         const DefaultTabController({
            Key key,
            @required this.length,
            this.initialIndex = 0,
            @required this.child,
          }) : assert(initialIndex != null),
               assert(length >= 0),
               assert(initialIndex >= 0 && initialIndex < length),
               super(key: key);
      • TabController
        TabController({ int initialIndex = 0, @required this.length, @required TickerProvider vsync })
            : assert(length != null && length >= 0),
              assert(initialIndex != null && initialIndex >= 0 && (length == 0 || initialIndex < length)),
              _index = initialIndex,
              _previousIndex = initialIndex,
              _animationController = AnimationController.unbounded(
                value: initialIndex.toDouble(),
                vsync: vsync,
              );
    • TabBar
      /**
          const TabBar({
          Key key,
          @required this.tabs,//显示的标签内容,一般使用Tab对象,也可以是其他的Widget
          this.controller,//TabController对象
          this.isScrollable = false,//是否可滚动
          this.indicatorColor,//指示器颜色
          this.indicatorWeight = 2.0,//指示器高度
          this.indicatorPadding = EdgeInsets.zero,//底部指示器的Padding
          this.indicator,//指示器decoration,例如边框等
          this.indicatorSize,//指示器大小计算方式,TabBarIndicatorSize.label跟文字等宽,TabBarIndicatorSize.tab跟每个tab等宽
          this.labelColor,//选中label颜色
          this.labelStyle,//选中label的Style
          this.labelPadding,//每个label的padding值
          this.unselectedLabelColor,//未选中label颜色
          this.unselectedLabelStyle,//未选中label的Style
          }) : assert(tabs != null),
          assert(isScrollable != null),
          assert(indicator != null || (indicatorWeight != null && indicatorWeight > 0.0)),
          assert(indicator != null || (indicatorPadding != null)),
          super(key: key);
       */
      • Tab
        const Tab({
            Key key,
            this.text,
            this.icon,
            this.child,
          }) : assert(text != null || child != null || icon != null),
               assert(!(text != null && null != child)), // TODO(goderbauer): https://github.com/dart-lang/sdk/issues/34180
               super(key: key);
    • TabBarView
        const TabBarView({
          Key key,
          @required this.children, //Tab页内容页组件数组集合
          this.controller, //TabController对象
          this.physics,
          this.dragStartBehavior = DragStartBehavior.start,
        }) : assert(children != null),
             assert(dragStartBehavior != null),
             super(key: key);

    四,创建标签栏

    • 1.创建TabController
      • 使用默认的DefaultController
         /**2.创建Tabbar */
          @override
          Widget build(BuildContext context) {
            // TODO: implement build
            return new DefaultTabController(
                length: myTabs.length,
                child:  new Scaffold(
                  //AppBar
                  appBar:new AppBar(
                    title: new Text('顶部标签栏'),
                    bottom: new TabBar(
                      tabs: myTabs, //标签数组
                      indicatorColor: Colors.blue,//指示器的颜色
                      isScrollable: true,//是否滑动
                    ),
                  ) ,
        
          /**3.绑定Tabbar 和 TabBarView */
                  //body
                  body: new TabBarView(
                    children: myTabs.map((Tab tab){
                        return new Center( child: new Text(tab.text));
                    }).toList(),
                  ),
                ),
            );
          }
      • 使用自定义的TabController的
        class TabBarDemoState extends State<TabBarDemo>
            with SingleTickerProviderStateMixin {
          TabController _tabController; //定义tabcontroller变量
        
          @override
          void dispose() {
            _tabController.dispose(); //销毁
            super.dispose();
          }
        
          void initState() {
            super.initState();
            _tabController = new TabController(vsync: this, length: 3); //创建
          }
        
          @override
          Widget build(BuildContext context) {
            return new Scaffold(
              appBar: new AppBar(
                title: new Text('顶部tab切换'),
                bottom: new TabBar(
                  tabs: <Widget>[
                    new Tab(
                      icon: new Icon(Icons.directions_bike),
                    ),
                    new Tab(
                      icon: new Icon(Icons.directions_boat),
                    ),
                    new Tab(
                      icon: new Icon(Icons.directions_bus),
                    ),
                  ],
                  controller: _tabController, //tabbar与自定义的tabcontroller绑定
                ),
              ),
              body: new TabBarView(
                controller: _tabController, //tabbarView与 自定义的tabController绑定
                children: <Widget>[
                  new Center(child: new Text('自行车')),
                  new Center(child: new Text('')),
                  new Center(child: new Text('巴士')),
                ],
              ),
            );
          }
    • 2.构建Tab数据/TabBarView数据
      /**1. 创建Tab数据 */
        final List<Tab> myTabs = <Tab>[
            new Tab(icon: new Icon(Icons.home),
            text:'首页',
            ),
            new Tab(
              icon: new Icon(Icons.message),
               text:'个人信息',
            ),
            
            new Tab(
              icon: new Icon(Icons.camera),
              text:'朋友圈',
            ),
            new Tab(
              icon: new Icon(Icons.access_alarm),
              text: '闹钟',
            )
        ];
    • 3. 创建Tabbar
      appBar:new AppBar(
                  title: new Text('顶部标签栏'),
                  bottom: new TabBar(
                    tabs: myTabs, //标签数组
                    indicatorColor: Colors.blue,//指示器的颜色
                    isScrollable: true,//是否滑动
                  ),
      )
    • 4.绑定TabBar 和 TabBarView
      /**3.绑定Tabbar 和 TabBarView */
                //body
                body: new TabBarView(
                  children: myTabs.map((Tab tab){
                      return new Center( child: new Text(tab.text));
                  }).toList(),
                ),
    • 5.全部代码
      import 'package:flutter/material.dart';
      
      void main() => runApp(MyApp());
      
      class MyApp extends StatelessWidget {
          @override
          Widget build(BuildContext context) {
          // TODO: implement build
          return new MaterialApp(
            title: '顶部标签栏',
            theme: new ThemeData(
              primaryColor: Colors.red
            ),
            home: new App(),
          );
        }
      }
      
      class App extends StatelessWidget {
      
        /**1. 创建Tab数据 */
        final List<Tab> myTabs = <Tab>[
            new Tab(icon: new Icon(Icons.home),
            text:'首页',
            ),
            new Tab(
              icon: new Icon(Icons.message),
               text:'个人信息',
            ),
            
            new Tab(
              icon: new Icon(Icons.camera),
              text:'朋友圈',
            ),
            new Tab(
              icon: new Icon(Icons.access_alarm),
              text: '闹钟',
            )
        ];
         
        /**2.创建Tabbar */
        @override
        Widget build(BuildContext context) {
          // TODO: implement build
          return new DefaultTabController(
              length: myTabs.length,
              child:  new Scaffold(
                //AppBar
                appBar:new AppBar(
                  title: new Text('顶部标签栏'),
                  bottom: new TabBar(
                    tabs: myTabs, //绑定标签数组
                    indicatorColor: Colors.blue,//指示器的颜色
                    isScrollable: true,//是否滑动
                  ),
                ) ,
      
        /**3.绑定Tabbar 和 TabBarView */
                //body
                body: new TabBarView(
                  children: myTabs.map((Tab tab){
                      return new Center( child: new Text(tab.text));
                  }).toList(),
                ),
              ),
          );
        }
      }

    五,总结

    TabBarView和TabBar都有一个TabController的参数,TabbarView和TabBar就是由TabController来控制同步,点击某个Tab后,要同步显示对应的TabBarView,创建TabController有两种方式:

    • 第一种:使用系统自带的DefaultTabController,在Scaffold套一层DefaultTabController,这种方式TabBarView会自动查找这个tabController。
      @override
      Widget build(BuildContext context) {
         return new DefaultTabController();
      }
    • 第二种是自己定义一个TabController,实现SingleTickerProviderStateMixin
      参考上面“使用自定tabcontroller代码”
  • 相关阅读:
    Python随笔——Map之键对应多值的处理
    Python操作cx_Oracle笔记
    jmeter进阶之Beanshell引用Java代码
    碎片记录——JMeter之 http post json对象与参数化调用,以及beanshell 引用Java源码
    java源码生成可运行jar
    小记:web安全测试之——固定session漏洞
    Git关联JIRA的issue
    APP稳定性测试-monkey执行
    maven之assembly插件
    wrapper配置文件详解
  • 原文地址:https://www.cnblogs.com/lxlx1798/p/11078901.html
Copyright © 2011-2022 走看看