Flutter入门: TabBar 详解

Auth:𝕏𝕏       Date:2024/04/28       Cat:编程       Word:共10555字

当前版本 Flutter 3.19.5

前言

TabBar 是用于创建选项卡式导航栏的组件。通常创建为 AppBar 的 AppBar.bottom 部分并与 TabBarView 结合使用, 它通常与TabBarView一起使用,TabBar用于显示选项卡的标签,而TabBarView用于显示与选中标签相关联的内容。

我们既可以手动创建一个 TabController ,也能够直接使用 DefaultTabController widget。最简单的选择是使用 DefaultTabController widget,因为它能够创建出一个可供所有子 widgets 使用的 TabController。

手动创建一个 TabController

class DemoState extends State with TickerProviderStateMixin {
  late TabController _tabController;

  @override
  void initState() {
    super.initState();
    _tabController = TabController(length: 3, vsync: this);
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        toolbarHeight: 0,
        bottom: TabBar(
          controller: _tabController,
          tabs: const [
            Tab(icon: Icon(Icons.directions_bike)),
            Tab(icon: Icon(Icons.directions_boat)),
            Tab(icon: Icon(Icons.directions_car)),
          ],
        ),
      ),
      body: TabBarView(
        controller: _tabController,
        children: [
          Icon(Icons.directions_bike),
          Icon(Icons.directions_boat),
          Icon(Icons.directions_car),
        ]
      )
    );
  }
}

直接使用 DefaultTabController

DefaultTabController(
  length: 3,
  child: Scaffold(
    appBar: AppBar(
      toolbarHeight: 0,
      bottom: TabBar(
        tabs: [
          Tab(icon: Icon(Icons.directions_bike)),
          Tab(icon: Icon(Icons.directions_boat)),
          Tab(icon: Icon(Icons.directions_car)),
        ],
      ),
    ),
    body: TabBarView(
      children: [
        Icon(Icons.directions_bike),
        Icon(Icons.directions_boat),
        Icon(Icons.directions_car),
      ]
    )
  ),
);

TabBar API

属性

属性一览

automaticIndicatorColorAdjustment: 是否自动调整indicatorColor

默认为 true, 当指示器颜色(indicatorColor) 与 AppBar 的背景色相同时会自动调整成 Colors.white

实现

final bool automaticIndicatorColorAdjustment;

示例

Flutter入门:  TabBar 详解 - 第1张图片

DefaultTabController(
  length: 3,
  child: Scaffold(
    appBar: AppBar(
      toolbarHeight: 0,
      backgroundColor: Colors.red,
      bottom: TabBar(
        indicatorColor: Colors.red,
        automaticIndicatorColorAdjustment: true,
        tabs: [
          Tab(icon: Icon(Icons.directions_bike)),
          Tab(icon: Icon(Icons.directions_boat)),
          Tab(icon: Icon(Icons.directions_car)),
        ],
      ),
    ),
  ),
);

controller: 控制tab的控制器

实现

final TabController? controller;

示例

class DemoState extends State with TickerProviderStateMixin {
  late TabController _tabController;

  @override
  void initState() {
    super.initState();
    _tabController = TabController(length: 3, vsync: this);
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        toolbarHeight: 0,
        bottom: TabBar(
          controller: _tabController,
          tabs: const [
          Tab(icon: Icon(Icons.directions_bike)),
          Tab(icon: Icon(Icons.directions_boat)),
          Tab(icon: Icon(Icons.directions_car)),
          ],
        ),
      ),
      body: TabBarView(
        controller: _tabController,
        children: [
          Icon(Icons.directions_bike),
          Icon(Icons.directions_boat),
          Icon(Icons.directions_car),
        ]
      )
    );
  }
}

dividerColor: 分隔线的颜色

实现

final Color? dividerColor;

示例

Flutter入门:  TabBar 详解 - 第2张图片

DefaultTabController(
  length: 3,
  child: Scaffold(
    appBar: AppBar(
      toolbarHeight: 0,
      bottom: TabBar(
        dividerColor: Colors.red,
        tabs: [
          Tab(icon: Icon(Icons.directions_bike)),
          Tab(icon: Icon(Icons.directions_boat)),
          Tab(icon: Icon(Icons.directions_car)),
        ],
      ),
    ),
  ),
);

dividerHeight: 分隔线的高度

实现

final double? dividerHeight;

示例

Flutter入门:  TabBar 详解 - 第3张图片

DefaultTabController(
  length: 3,
  child: Scaffold(
    appBar: AppBar(
      toolbarHeight: 0,
      bottom: TabBar(
        dividerHeight: 10,
        tabs: [
          Tab(icon: Icon(Icons.directions_bike)),
          Tab(icon: Icon(Icons.directions_boat)),
          Tab(icon: Icon(Icons.directions_car)),
        ],
      ),
    ),
  ),
);

dragStartBehavior: 决定TabBar如何响应拖动手势

[DragStartBehavior.start],则在检测到拖动手势时将开始滚动拖动行为

[DragStartBehavior.down],它将在首次检测到向下事件时开始

默认为 DragStartBehavior.start

实现

final DragStartBehavior dragStartBehavior;

示例

DefaultTabController(
  length: 3,
  child: Scaffold(
    appBar: AppBar(
      toolbarHeight: 0,
      bottom: TabBar(
        dragStartBehavior: DragStartBehavior.start,
        tabs: [
          Tab(icon: Icon(Icons.directions_bike)),
          Tab(icon: Icon(Icons.directions_boat)),
          Tab(icon: Icon(Icons.directions_car)),
        ],
      ),
    ),
  ),
);

enableFeedback: 检测到的手势是否应提供声音和/或触觉反馈

默认为 true

实现

final bool? enableFeedback;

示例

DefaultTabController(
  length: 3,
  child: Scaffold(
    appBar: AppBar(
      toolbarHeight: 0,
      bottom: TabBar(
        enableFeedback: true,
        tabs: [
          Tab(icon: Icon(Icons.directions_bike)),
          Tab(icon: Icon(Icons.directions_boat)),
          Tab(icon: Icon(Icons.directions_car)),
        ],
      ),
    ),
  ),
);

indicator: 设置选中Tab指示器的外观

实现

final Decoration? indicator;

示例

Flutter入门:  TabBar 详解 - 第4张图片

DefaultTabController(
  length: 3,
  child: Scaffold(
    appBar: AppBar(
      toolbarHeight: 0,
      bottom: TabBar(
        indicator: BoxDecoration(
          gradient: LinearGradient(colors: [
            Colors.orange,
            Colors.green
          ]),
        ),
        tabs: [
          Tab(icon: Icon(Icons.directions_bike)),
          Tab(icon: Icon(Icons.directions_boat)),
          Tab(icon: Icon(Icons.directions_car)),
        ],
      ),
    ),
  ),
);

indicatorColor: 指示器颜色

实现

final Color? indicatorColor;

示例

DefaultTabController(
  length: 3,
  child: Scaffold(
    appBar: AppBar(
      toolbarHeight: 0,
      bottom: TabBar(
        indicatorColor: Colors.red,
        tabs: [
          Tab(icon: Icon(Icons.directions_bike)),
          Tab(icon: Icon(Icons.directions_boat)),
          Tab(icon: Icon(Icons.directions_car)),
        ],
      ),
    ),
  ),
);

indicatorPadding: 指示器间距

默认为 EdgeInsets.zero, 设置 EdgeInsets 的 top 属性没有作用

实现

final EdgeInsetsGeometry indicatorPadding;

示例

Flutter入门:  TabBar 详解 - 第5张图片

DefaultTabController(
  length: 3,
  child: Scaffold(
    appBar: AppBar(
      toolbarHeight: 0,
      bottom: TabBar(
        indicatorPadding: EdgeInsets.only(left: 5, right: 5, bottom: 5),
        tabs: [
          Tab(icon: Icon(Icons.directions_bike)),
          Tab(icon: Icon(Icons.directions_boat)),
          Tab(icon: Icon(Icons.directions_car)),
        ],
      ),
    ),
  ),
);

indicatorSize: 指示器大小

TabBarIndicatorSize.tab(默认): 选定选项卡指示器的大小是相对于选项卡的整体边界定义的

TabBarIndicatorSize.label : 则相对于选项卡小部件的边界定义

实现

final TabBarIndicatorSize? indicatorSize;

示例

Flutter入门:  TabBar 详解 - 第6张图片

DefaultTabController(
  length: 3,
  child: Scaffold(
    appBar: AppBar(
      toolbarHeight: 0,
      bottom: TabBar(
        indicatorSize: TabBarIndicatorSize.label,
        tabs: [
          Text('这是一个非常长的Tab'),
          Tab(icon: Icon(Icons.directions_boat)),
          Tab(icon: Icon(Icons.directions_car)),
        ],
      ),
    ),
  ),
);

indicatorWeight: 指示器宽度

如果ThemeData.useMaterial3为 true 并且使用TabBar创建主选项卡栏,则默认值为 3.0。如果提供的值小于 3.0,则使用默认值。

如果ThemeData.useMaterial3为 true 且使用TabBar.secondary创建辅助选项卡栏,则默认值为 2.0。

如果ThemeData.useMaterial3为 false,则默认值为 2.0。

实现

final double indicatorWeight;

示例

Flutter入门:  TabBar 详解 - 第7张图片

DefaultTabController(
  length: 3,
  child: Scaffold(
    appBar: AppBar(
      toolbarHeight: 0,
      bottom: TabBar(
        indicatorWeight: 20,
        tabs: [
          Tab(icon: Icon(Icons.directions_bike)),
          Tab(icon: Icon(Icons.directions_boat)),
          Tab(icon: Icon(Icons.directions_car)),
        ],
      ),
    ),
  ),
);

isScrollable: 是否可以滚动

默认为 false

实现

final bool isScrollable;

示例

Flutter入门:  TabBar 详解 - 第8张图片

DefaultTabController(
  length: 9,
  child: Scaffold(
    appBar: AppBar(
      toolbarHeight: 0,
      bottom: TabBar(
        isScrollable: true,
        tabs: [
          Tab(icon: Icon(Icons.directions_bike)),
          Tab(icon: Icon(Icons.directions_boat)),
          Tab(icon: Icon(Icons.directions_car)),
          Tab(icon: Icon(Icons.directions_bike)),
          Tab(icon: Icon(Icons.directions_boat)),
          Tab(icon: Icon(Icons.directions_car)),
          Tab(icon: Icon(Icons.directions_bike)),
          Tab(icon: Icon(Icons.directions_boat)),
          Tab(icon: Icon(Icons.directions_car)),
        ],
      ),
    ),
  ),
);

labelColor: 所选选项卡标签的颜色

实现

final Color? labelColor;

示例

Flutter入门:  TabBar 详解 - 第9张图片

DefaultTabController(
  length: 3,
  child: Scaffold(
    appBar: AppBar(
      toolbarHeight: 0,
      bottom: TabBar(
        labelColor: Colors.red,
        tabs: [
          Tab(icon: Icon(Icons.directions_bike)),
          Tab(icon: Icon(Icons.directions_boat)),
          Tab(icon: Icon(Icons.directions_car)),
        ],
      ),
    ),
  ),
);

labelPadding: 每个选项卡标签的左右间距

不能设置上下间距,主要用于显示文本使用

实现

final EdgeInsetsGeometry? labelPadding;

示例

Flutter入门:  TabBar 详解 - 第10张图片

DefaultTabController(
  length: 3,
  child: Scaffold(
    appBar: AppBar(
      toolbarHeight: 0,
      bottom: TabBar(
        labelPadding: EdgeInsets.only(left: 25, right: 25),
        tabs: [
          Text('这是一个非常长的Tab1'),
          Text('这是一个非常长的Tab2'),
          Tab(icon: Icon(Icons.directions_car)),
        ],
      ),
    ),
  ),
);

labelStyle: 所选选项卡标签的文本样式

实现

final TextStyle? labelStyle;

示例

Flutter入门:  TabBar 详解 - 第11张图片

DefaultTabController(
  length: 3,
  child: Scaffold(
    appBar: AppBar(
      toolbarHeight: 0,
      bottom: TabBar(
        labelStyle: TextStyle(
          color: Colors.green,
          backgroundColor: Colors.yellow,
        ),
        tabs: [
          Text('这是一个非常长的Tab1'),
          Text('这是一个非常长的Tab2'),
          Tab(icon: Icon(Icons.directions_car)),
        ],
      ),
    ),
  ),
);

onTap: 点击事件

实现

final ValueChanged<int>? onTap;

示例

DefaultTabController(
  length: 3,
  child: Scaffold(
    appBar: AppBar(
      toolbarHeight: 0,
      bottom: TabBar(
        onTap: (int index) {
          print('当前tab索引为:$index');
        },
        tabs: [
          Text('这是一个非常长的Tab1'),
          Text('这是一个非常长的Tab2'),
          Tab(icon: Icon(Icons.directions_car)),
        ],
      ),
    ),
  ),
);

overlayColor: 定义响应焦点、悬停和飞溅颜色

实现

final MaterialStateProperty<Color?>? overlayColor;

示例

DefaultTabController(
  length: 3,
  child: Scaffold(
    appBar: AppBar(
      toolbarHeight: 0,
      bottom: TabBar(
        overlayColor: MaterialStatePropertyAll(Colors.red),
        tabs: [
          Text('这是一个非常长的Tab1'),
          Text('这是一个非常长的Tab2'),
          Tab(icon: Icon(Icons.directions_car)),
        ],
      ),
    ),
  ),
);

padding: 标签栏左右的间距

实现

final EdgeInsetsGeometry? padding;

示例

Flutter入门:  TabBar 详解 - 第12张图片

DefaultTabController(
  length: 3,
  child: Scaffold(
    appBar: AppBar(
      toolbarHeight: 0,
      bottom: TabBar(
        padding: EdgeInsets.only(left: 30, right: 30),
        tabs: [
          Text('这是一个非常长的Tab1'),
          Text('这是一个非常长的Tab2'),
          Text('这是一个非常长的Tab3'),
        ],
      ),
    ),
  ),
);

physics: 滑动效果

如滑动到末端时,继续拉动,使用 ClampingScrollPhysics 实现Android下微光效果。

使用 BouncingScrollPhysics 实现iOS下弹性效果

默认根据系统来决定

实现

final ScrollPhysics? physics;

示例

DefaultTabController(
  length: 3,
  child: Scaffold(
    appBar: AppBar(
      toolbarHeight: 0,
      bottom: TabBar(
        physics: BouncingScrollPhysics(),
        tabs: [
          Text('这是一个非常长的Tab1'),
          Text('这是一个非常长的Tab2'),
          Text('这是一个非常长的Tab3'),
        ],
      ),
    ),
  ),
);

splashBorderRadius: 定义飞溅效果的边框圆角

实现

final BorderRadius? splashBorderRadius;

示例

DefaultTabController(
  length: 3,
  child: Scaffold(
    appBar: AppBar(
      toolbarHeight: 0,
      bottom: TabBar(
        splashBorderRadius: BorderRadius.only(
          topLeft: Radius.circular(10),
          topRight: Radius.circular(10),
        ),
        tabs: [
          Text('这是一个非常长的Tab1'),
          Text('这是一个非常长的Tab2'),
          Text('这是一个非常长的Tab3'),
        ],
      ),
    ),
  ),
);

tabAlignment: 选项卡的水平对齐方式

如果TabBar.isScrollable为 false,则仅支持TabAlignment.fill和 TabAlignment.center 。否则会抛出异常。

如果TabBar.isScrollable为 true,则仅支持TabAlignment.start、TabAlignment.startOffset和TabAlignment.center 。否则会抛出异常。

设置为 TabAlignment.center 时,文字会显示为一行

实现

final TabAlignment? tabAlignment;

示例

DefaultTabController(
  length: 3,
  child: Scaffold(
    appBar: AppBar(
      toolbarHeight: 0,
      bottom: TabBar(
        tabAlignment: TabAlignment.center,
        tabs: [
          Text('这是一个非常长的Tab1'),
          Tab(icon: Icon(Icons.directions_bike)),
          Tab(icon: Icon(Icons.directions_boat)),
        ],
      ),
    ),
  ),
);

tabs: Tab列表

实现

final List<Widget> tabs;

示例

DefaultTabController(
  length: 3,
  child: Scaffold(
    appBar: AppBar(
      toolbarHeight: 0,
      bottom: TabBar(
        tabs: [
          Tab(icon: Icon(Icons.directions_bike)),
          Tab(icon: Icon(Icons.directions_boat)),
          Tab(icon: Icon(Icons.directions_car)),
        ],
      ),
    ),
  ),
);

unselectedLabelColor: 未选中选项卡的颜色

实现

final Color? unselectedLabelColor;

示例

Flutter入门:  TabBar 详解 - 第13张图片

DefaultTabController(
  length: 3,
  child: Scaffold(
    appBar: AppBar(
      toolbarHeight: 0,
      bottom: TabBar(
        unselectedLabelColor: Colors.green,
        tabs: [
          Text('这是一个非常长的Tab1'),
          Tab(icon: Icon(Icons.directions_bike)),
          Tab(icon: Icon(Icons.directions_boat)),
        ],
      ),
    ),
  ),
);

unselectedLabelStyle: 未选中选项卡的样式

实现

final TextStyle? unselectedLabelStyle;

示例

Flutter入门:  TabBar 详解 - 第14张图片

DefaultTabController(
  length: 3,
  child: Scaffold(
    appBar: AppBar(
      toolbarHeight: 0,
      bottom: TabBar(
        unselectedLabelStyle: TextStyle(
          color: Colors.green,
          backgroundColor: Colors.yellow,
        ),
        tabs: [
          Text('这是一个非常长的Tab1'),
          Tab(icon: Icon(Icons.directions_bike)),
          Tab(icon: Icon(Icons.directions_boat)),
        ],
      ),
    ),
  ),
);

...完结...

《Flutter入门: TabBar 详解》留言数:0

发表留言