flutter3.0学习笔记

顶部导航栏TabBar

Preview
  • TabBar
  • TabController
  • DefaultTabController 构造
  • TabBar
  • isScrollable
  • indicatorColor、indicatorWeight、indicatorPadding
  • indicator
  • labelColor、unselectedLabelColor
  • labelPadding
  • labelStyle\unselectedLabelStyle
  • onTap
  • TabBarView

TabBar

一般来说在Flutter中创建Tab布局,需要实现以下步骤:

  • 创建一个TabController,
  • 创建一个TabBar,
  • 创建一个TabBarView。

TabController

TabController的作用是将所选Tab与它的内容同步,可以手动创建TabController,或者使用可用的Widget(称为DefaultTabController)来支持一些常用功能。其构造:

TabController(
    {int initialIndex: 0,//默认激活项
    @required int length,//长度
    @required TickerProvider vsync
     }
)
DefaultTabController 构造
const DefaultTabController(
    {Key key,
    @required int length,
    int initialIndex: 0,
    @required Widget child}
)

例子:

DefaultTabController(
  length: 3,
  child: null
);

TabBar

其构造:

const TabBar({
    super.key,
    required this.tabs,
    this.controller,
    this.isScrollable = false,//是否可滑动
    this.padding,
    this.indicatorColor,//指定当前选定选项卡下线的颜色
    this.automaticIndicatorColorAdjustment = true,
    this.indicatorWeight = 2.0,//下划线宽度
    this.indicatorPadding = EdgeInsets.zero,//当前选定的选项卡下的行指定水平填充
    this.indicator,//当前选定选项卡的外观
    this.indicatorSize,
    this.labelColor,//当前所选Tab的标签指定字体颜色
    this.labelStyle,//选定选项卡的标签上指定文本样式
    this.labelPadding,//选项填充
    this.unselectedLabelColor,//未选中的选项卡的Tab指定字体颜色
    this.unselectedLabelStyle,//未选中的选项卡的标签上指定文本样式
    this.dragStartBehavior = DragStartBehavior.start,
    this.overlayColor,
    this.mouseCursor,
    this.enableFeedback,
    this.onTap,
    this.physics,
    this.splashFactory,
    this.splashBorderRadius,
  }) 

TabBar示例代码:

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

isScrollable

多个tab选项时,向左滑动。 image.png

import 'package:flutter/material.dart';
class AppPage extends StatelessWidget {
  const AppPage({Key? key}) : super(key: key);
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'AppPage',
      theme: ThemeData(
        primarySwatch: Colors.blue,
        visualDensity: VisualDensity.adaptivePlatformDensity,
      ),
      home: TabBarPage(),
    );
  }
}
class TabBarPage extends StatelessWidget {
  const TabBarPage({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return DefaultTabController(
      length: 6,
      child: Scaffold(
          appBar: AppBar(
            bottom:  TabBar(
              tabs: [
                Row (children: const [Icon(Icons.directions_car), SizedBox(width:5), Text("Car")]),
                Row (children: const [Icon(Icons.directions_transit), SizedBox(width:5), Text("Transit")]),
                Row (children: const [Icon(Icons.directions_bike), SizedBox(width:5), Text("Bike")]),
                Row (children: const [Icon(Icons.directions_boat), SizedBox(width:5), Text("Boat")]),
                Row (children: const [Icon(Icons.directions_railway), SizedBox(width:5), Text("Railway")]),
                Row (children: const [Icon(Icons.directions_bus), SizedBox(width:5), Text("Bus")]),
              ],
              isScrollable: true,
            ),
            //背景色
            title: const Text('导航栏'),
            automaticallyImplyLeading: true,
          ),
          body: const TabBarView(
            children: [
              Center(child: Text("Car")),
              Center(child: Text("Transit")),
              Center(child: Text("Bike")),
              Center(child: Text("Boat")),
              Center(child: Text("Railway")),
              Center(child: Text("Bus"))
            ],
          )

      ),
    );

  }
}

如果想要调整Tab位置,可以用PreferredSize来加上我们的样式,比如例子向左对齐Tab:

bottom: PreferredSize(
  preferredSize: Size.fromHeight(40),
  child: Align(
    alignment: Alignment.centerLeft,
    child: TabBar(
      isScrollable: true,
      tabs: [ Row (children: [Icon(Icons.directions_car), SizedBox(width:5), Text("Car")]),
        Row (children: [Icon(Icons.directions_transit), SizedBox(width:5), Text("Transit")]),
        Row (children: [Icon(Icons.directions_bike), SizedBox(width:5), Text("Bike")])],
    ),
  ),
),

image.png

indicatorColor、indicatorWeight、indicatorPadding

tabs: [
    Row (children: const [Icon(Icons.directions_car), SizedBox(width:5), Text("Car")]),
    Row (children: const [Icon(Icons.directions_transit), SizedBox(width:5), Text("Transit")]),
    Row (children: const [Icon(Icons.directions_bike), SizedBox(width:5), Text("Bike")])
    ],
    indicatorColor: const Color(0xffE74C3C),
    indicatorWeight: 5,
    indicatorPadding: const EdgeInsets.only(right: 20.0),

image.png

indicator

indicator属性定义当前选定选项卡的外观。如果使用此属性,则其他属性(如indicatorColor,indicatorWeight和indicatorPadding)将被忽略。有四种方式写法:

image.png

 indicator: const ShapeDecoration(
    shape: UnderlineInputBorder(
      borderSide: BorderSide(
        color: Colors.transparent,
        width: 0,
        style: BorderStyle.solid
      ),
    ),
    gradient: LinearGradient(colors: [Color(0xff01ff80),Color(0xff0081ff)]),
  ),

image.png

labelColor、unselectedLabelColor

labelColor属性用于为当前所选Tab的标签指定字体颜色,unselectedLabelColor属性用于为未选中的选项卡的Tab指定字体颜色。

labelColor: Colors.red,
unselectedLabelColor: Colors.white,

image.png

labelPadding

labelPadding属性用于向Tab的每个标签添加填充。

labelPadding: const EdgeInsets.all(20.0),

image.png

labelStyle\unselectedLabelStyle

labelStyle属性用于在当前选定的选项卡的标签上指定文本样式。unselectedLabelStyle属性用于在未选中的选项卡的标签上指定文本样式。

labelStyle: const TextStyle(
    fontSize: 20,
    fontWeight: FontWeight.bold,
),
unselectedLabelStyle: const TextStyle(
    fontSize: 16,
),

image.png

onTap

onTap是一种回调函数,当用户点击TabBar上的一个Tab时调用。

class TabBarPage extends StatefulWidget {
  const TabBarPage({Key? key}) : super(key: key);

  @override
  State<TabBarPage> createState() => _TabBarPageState();
}

class _TabBarPageState extends State<TabBarPage> {
  @override
  Widget build(BuildContext context) {
    return DefaultTabController(
        length: 3,
        child: Scaffold(
          appBar: AppBar(
            title: const Text('TabBar导航栏'),
            bottom: TabBar(
              tabs: [
                Row (children: const [Icon(Icons.directions_car), SizedBox(width:5), Text("Car")]),
                Row (children: const [Icon(Icons.directions_transit), SizedBox(width:5), Text("Transit")]),
                Row (children: const [Icon(Icons.directions_bike), SizedBox(width:5), Text("Bike")])
              ],
              onTap: (index){
                setState(() {
                  print(index);
                });
              },
            ),
          ),

        ),
    );
  }
}

TabBarView

可以使用TabBarView包含与TabBar上每个Tab相对应的内容。其构造:

const TabBarView({
    super.key,
    required this.children,
    this.controller,
    this.physics,
    this.dragStartBehavior = DragStartBehavior.start,
    this.viewportFraction = 1.0,
    this.clipBehavior = Clip.hardEdge,
  })

例子:

TabBarView (
  children: [
    Icon(Icons.directions_car),
    Icon(Icons.directions_transit),
    Icon(Icons.directions_bike),
  ],
);