Flutter Widgets: TabBar

/ Flutter / 没有评论 / 560浏览

介绍

TabBar,是材料设计中很常用的一种横向标签页。在Android原生开发中,我们常用TabLayout或者一些常用的标签页开源库,来实现并行界面的横向滑动展示,在Flutter的世界中,TabBar有着相同的作用。通常,我们会在AppBar的底部部分结合TabBarView来使用TabBar。

类结构

构建TabBar,我们需要使用到多个Tab对象,用Tab来承载我们需要展示的Text和Icon内容,多个Tab呈现在用户面前,供用户点击切换内容。TabBar的构造方法中包含很多属性值或者变量。 这里写图片描述

属性意义
tabs一般使用Tab对象,当然也可以是其他的Widget
controllerTabController对象
isScrollable是否可滚动
indicatorColor指示器颜色
indicatorWeight指示器厚度
indicatorPadding底部指示器的Padding
indicator指示器decoration,例如边框等
indicatorSize指示器大小计算方式
labelColor选中Tab文字颜色
labelStyle选中Tab文字Style
unselectedLabelColor未选中Tab中文字颜色
unselectedLabelStyle未选中Tab中文字style

实践

tabs & isScrollable

tabs,List< Widget> ,一般我们使用Tab对象数组来填充这部分内容,因为Tab对象本身涵盖了我们常用的文字Tab,图标Tab或者是二者结合的形式。基本可以满足日常开发需求。 isScrollable,一般在Tab比较多的情况使用,默认为false,表示固定,每个tab的宽度将会以屏幕宽度为总和均分。若为true,超出屏幕范围的tabs,我们可以通过左右滚动访问。类似于HorizontalScrollView。

final List<Tab> myTabs = <Tab>[
    new Tab(text: '语文'),
    new Tab(text: '数学'),
    new Tab(text: '英语'),
    new Tab(text: '化学'),
    new Tab(text: '物理'),
    new Tab(text: '政治'),
    new Tab(text: '经济'),
    new Tab(text: '体育'),
  ];
  ……
  Widget build(BuildContext context) {
  return new DefaultTabController(
    length: myTabs.length,
    child: new Scaffold(
      appBar: new AppBar(
        bottom: new TabBar(
          tabs: myTabs,
          isScrollable: true,
        ),
      ),
      body: new TabBarView(
        children: myTabs.map((Tab tab) {
          return new Center(child: new Text(tab.text));
        }).toList(),
      ),
    ),
  );
}

这里写图片描述

indicatorColor&indicatorWeight&indicatorPadding

indicatorColor: Colors.red,
indicatorWeight: 15.0,
indicatorPadding: new EdgeInsets.only(bottom: 30.0),

这里写图片描述

indicator

定义被选中的指示器的外观

  indicator: new ShapeDecoration(shape: new Border.all(color: Colors.redAccent, width: 1.0)),

这里写图片描述

indicatorSize

定义指示器大小的计算方式,值取至TabBarIndicatorSize 这个枚举类型。从注释和下面的对比图片,可以显然看出,一个是以label的宽度为计算方式,一个是以整个Tab的宽度为计算方式。

enum TabBarIndicatorSize {
  /// The tab indicator's bounds are as wide as the space occupied by the tab
  /// in the tab bar: from the right edge of the previous tab to the left edge
  /// of the next tab.
  tab,

  /// The tab's bounds are only as wide as the (centered) tab widget itself.
  ///
  /// This value is used to align the tab's label, typically a [Tab]
  /// widget's text or icon, with the selected tab indicator.
  label,
}

indicatorSize: TabBarIndicatorSize.label

这里写图片描述

indicatorSize: TabBarIndicatorSize.tab

这里写图片描述

labelColor&labelStyle&unselectedLabelColor&unselectedLabelStyle

定义选中Tab和未选中Tab中文字的颜色和风格

 labelColor: Colors.white,
 labelStyle: new TextStyle(fontSize: 16.0),
 unselectedLabelColor: Colors.black,
 unselectedLabelStyle: new TextStyle(fontSize: 12.0)

这里写图片描述

TabController

TabBar和TabBarView通过公用的TabController对象来实现,互相之间的协调配合。 默认使用的是DefaultTabController.of(context)。用法如下。

  Widget build(BuildContext context) {
    return new DefaultTabController(length: myTabs.length,
        child:
        new Scaffold(
          appBar: new AppBar(
            bottom: new TabBar(
              tabs: myTabs,
              isScrollable: true,
              indicatorSize: TabBarIndicatorSize.tab,
              labelColor: Colors.white,
              labelStyle: new TextStyle(fontSize: 16.0),
              unselectedLabelColor: Colors.black,
              unselectedLabelStyle: new TextStyle(fontSize: 12.0),
            ),
          ),
          body: new TabBarView(
            children: myTabs.map((Tab tab) {
              return new Center(child: new Text(tab.text));
            }).toList(),
          ),
        ),
    );
  }

当然,我们也能自定义TabController,保持TabBar和TabBarView使用的TabController一致即可。下面是官文中的使用样例。好东西都在源码中啊,很多不理解的内容,通过多阅读源码,可以找到头绪。

class MyDemo extends StatelessWidget {
  final List<Tab> myTabs = <Tab>[
    new Tab(text: 'LEFT'),
    new Tab(text: 'RIGHT'),
  ];
  @override
  Widget build(BuildContext context) {
    return new DefaultTabController(
      length: myTabs.length,
      child: new Scaffold(
        appBar: new AppBar(
          bottom: new TabBar(
            tabs: myTabs,
          ),
        ),
        body: new TabBarView(
          children: myTabs.map((Tab tab) {
            return new Center(child: new Text(tab.text));
          }).toList(),
        ),
      ),
    );
  }
}