Flutter开发者

TabBar

2018-04-22

前言

后台留言说这个Widget没有讲到,好吧今天就把TabBar吧。

TabBar在客户端的表现形式是一般展示在appBar的下面,做同一级别不同类型界面的展示工作。

确实,在平时我们的应用中是非常常见的,所以讲一下也不过分哈。

TabBar

还是首先来你看下构造方法吧

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

const TabBar({
Key key,
@required this.tabs,//WidgetList,一般使用系统提供的Tab作为Widget哦
this.controller,//控制器
this.isScrollable: false,//总内容超出自动宽展区域并可以滚动
this.indicatorColor,//指示器颜色
this.indicatorWeight: 2.0,指示器宽度
this.indicatorPadding: EdgeInsets.zero,//指示器padding
this.indicator,//自定义指示器
this.indicatorSize,//指示器大小
this.labelColor,//文字颜色
this.labelStyle,//文字style
this.unselectedLabelColor,//未选中文字颜色
this.unselectedLabelStyle,//未选中文字style
})

其中只有tabs参数势必须的,其他的参数都会根据你app的主题曲自动设置相应的参数。

那么这个Tab又是什么东西呢?我们还是再来看下Tab的构造方法吧

1
2
3
4
5
6
const Tab({
Key key,
this.text,
this.icon,
this.child,
})

相比于TabBar,Tab这个WIdget就显得非常简单,他就是一个最基本的组件,我们 可以选择性的填入text,icon或者子Widget

我们仅仅使用这两个组件就可以显示一个TabBar可以了,但是如果想要做到TabBar与下面内容区域的关联还需要用到TabView这个Widget哦。

TabView实际上就是用来关联Tab与内容区域的一个中间件。

今天我们来看个官方的例子(不要问我为什么用官方例子,我懒啊……)

看个官方例子

官方这个例子能够很好说明下这个TabBar的用法。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
import 'package:flutter/material.dart';
void main() {
runApp(new TabbedAppBarSample());
}
class TabbedAppBarSample extends StatelessWidget {
@override
Widget build(BuildContext context) {
return new MaterialApp(
home: new DefaultTabController(
length: choices.length,
child: new Scaffold(
appBar: new AppBar(
title: const Text('Tabbed AppBar'),
bottom: new TabBar(
isScrollable: true,
tabs: choices.map((Choice choice) {
return new Tab(
text: choice.title,
icon: new Icon(choice.icon),
);
}).toList(),
),
),
body: new TabBarView(
children: choices.map((Choice choice) {
print("init"+choice.title);
return new Padding(
padding: const EdgeInsets.all(16.0),
child: new ChoiceCard(choice: choice),
);
}).toList(),
),
),
),
);
}
}

class Choice {
const Choice({ this.title, this.icon });
final String title;
final IconData icon;
}

const List<Choice> choices = const <Choice>[
const Choice(title: 'CAR', icon: Icons.directions_car),
const Choice(title: 'BICYCLE', icon: Icons.directions_bike),
const Choice(title: 'BOAT', icon: Icons.directions_boat),
const Choice(title: 'BUS', icon: Icons.directions_bus),
const Choice(title: 'TRAIN', icon: Icons.directions_railway),
const Choice(title: 'WALK', icon: Icons.directions_walk),
];

class ChoiceCard extends StatelessWidget {
const ChoiceCard({ Key key, this.choice }) : super(key: key);

final Choice choice;

@override
Widget build(BuildContext context) {
final TextStyle textStyle = Theme.of(context).textTheme.display1;
return new Card(
color: Colors.white,
child: new Center(
child: new Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
new Icon(choice.icon, size: 128.0, color: textStyle.color),
new Text(choice.title, style: textStyle),
],
),
),
);
}
}

首先,我们建立了一个Choice对象,有title和icon两个属性

1
2
3
4
5
class Choice {
const Choice({ this.title, this.icon });
final String title;
final IconData icon;
}

然后我们初始化List数据,这样我们就拿到了一个长度为6的List数据

1
2
3
4
5
6
7
8
const List<Choice> choices = const <Choice>[
const Choice(title: 'CAR', icon: Icons.directions_car),
const Choice(title: 'BICYCLE', icon: Icons.directions_bike),
const Choice(title: 'BOAT', icon: Icons.directions_boat),
const Choice(title: 'BUS', icon: Icons.directions_bus),
const Choice(title: 'TRAIN', icon: Icons.directions_railway),
const Choice(title: 'WALK', icon: Icons.directions_walk),
];

然后我们定义了一个内容区域的Widget,并根据传递来的Choice对象来初始化Widget

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24

class ChoiceCard extends StatelessWidget {
const ChoiceCard({ Key key, this.choice }) : super(key: key);

final Choice choice;

@override
Widget build(BuildContext context) {
final TextStyle textStyle = Theme.of(context).textTheme.display1;
return new Card(
color: Colors.white,
child: new Center(
child: new Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
new Icon(choice.icon, size: 128.0, color: textStyle.color),
new Text(choice.title, style: textStyle),
],
),
),
);
}
}

最后在TabbedAppBarSample Wdiget中,我们通过构建的choices数据创建Tab并且通过TabView关联ChoiceCard,这样一来我们就可以根据下面内容区域的滑动来更新tab的显示或者根据tab选中的变化来更新下面的内容区域了。

那么,还是来看下效果吧:

试一试其他参数

接下来,我们来尝试修改下TabBar选中时的指示器颜色

我们单单给TabBar加了个 indicatorColor: Colors.red,我们再来看下效果

可以看到,TabBar的指示器颜色已经变成了红色

那么接下来我们来设置下上面文字来图标选中时和未选中时的颜色

labelColor: Colors.orange,
unselectedLabelColor: Colors.white,

我们依旧仅仅给TabBar加上上面的参数再来看下效果

小结

使用TabBar、Tab、TabView可以很方便的实现页签切换效果,在官方这个例子中,把对象、数据初始化和自定义Widget都写在了一个文件中,这样大家看起来可能会比较不好理解,大家可以把这个逻辑都抽离出到单独的文件中再去看就比较好理解了。

使用支付宝打赏
使用微信打赏

若你觉得我的文章对你有帮助,欢迎点击上方按钮对我打赏

打赏请备注姓名或者昵称,方便我后期统计哦

关注公众号,及时查阅最新文章