Tab
页的控制器,用于定义Tab
标签和内容页的坐标,还可配置标签页的切换动画效果等。TabController一般放入有状态控件中使用,以适应标签页数量和内容有动态变化的场景,如果标签页在APP中是静态固定的格局,则可以在无状态控件中加入简易版的DefaultTabController以提高运行效率,毕竟无状态控件要比有状态控件更省资源,运行效率更快。
TabBarTab
页的Title
控件,切换Tab
页的入口,一般放到AppBar
控件下使用,内部有*Title属性。其子元素按水平横向排列布局,如果需要纵向排列,请使用Column
或ListView
控件包装一下。子元素为Tab
类型的数组。
TabBarViewTab
页的内容容器,其内放置Tab
页的主体内容。子元素可以是多个各种类型的控件。
先看一下Tab的构造方法:
TabBar({
Key key,
@required this.tabs,
this.controller,
this.isScrollable: false,
this.indicatorColor,
this.indicatorWeight: 2.0,
this.indicatorPadding: EdgeInsets.zero,
this.indicator,
this.indicatorSize,
this.labelColor,
this.labelStyle,
this.unselectedLabelColor,
this.unselectedLabelStyle,
})
属性 | 意义 |
---|---|
tabs | 一般使用Tab对象,当然也可以是其他的Widget |
controller | TabController对象 |
isScrollable | 是否可滚动 |
indicatorColor | 指示器颜色 |
indicatorWeight | 指示器厚度 |
indicatorPadding | 底部指示器的Padding |
indicator | 指示器decoration,例如边框等 |
indicatorSize | 指示器大小计算方式 |
labelColor | 选中Tab文字颜色 |
labelStyle | 选中Tab文字Style |
unselectedLabelColor | 未选中Tab中文字颜色 |
unselectedLabelStyle | 未选中Tab中文字style |
import 'package:flutter/material.dart';
class MyHomePage extends StatefulWidget {
@override
createState() => new MyHomePageState();
}
class MyHomePageState extends State {
final List myTabs = [
Tab(text: '明教'),
Tab(text: '霸刀'),
Tab(text: '天策'),
Tab(text: '纯阳'),
Tab(text: '少林'),
Tab(text: '藏剑'),
Tab(text: '七秀'),
Tab(text: '五毒'),
];
@override
Widget build(BuildContext context) {
return DefaultTabController(
length: myTabs.length,
child: Scaffold(
appBar: AppBar(
backgroundColor: Colors.blue,
title: TabBar(
tabs: myTabs,
isScrollable: true,
indicatorColor: Colors.red,
labelColor: Colors.white,
),
),
body: TabBarView(
children: myTabs
.map((Tab tab) => Center(child: Text(tab.text)))
.toList()),
),
);
}
}
Flutter中为了节约内存不会保存widget的状态,widget都是临时变量。当我们使用TabBar,TabBarView是我们就会发现,切换tab后再重新切换回上一页面,这时候tab会重新加载重新创建,体验很不友好。Flutter出于自己的设计考虑并没有延续android的ViewPager这样的缓存页面设计,毕竟控件两端都要开发,目前还在beta版本有很多设计还不够完善,但是设计的拓展性没得说,flutter还是为我们提供了解决办法。我们可以强制widget不显示情况下保留状态,下回再加载时就不用重新创建了。
AutomaticKeepAliveClientMixin
是一个抽象状态,使用也很简单,我们只需要用我们自己的状态继承这个抽象状态,并实现 wantKeepAlive
方法即可。
继承这个状态后,widget在不显示之后也不会被销毁仍然保存在内存中,所以慎重使用这个方法。
详细官方文档请看这里。
这里还有一个说的比较详细的 demo。
/*
* Created by 李卓原 on 2018/9/13.
* email: [email protected]
*
*/
import 'package:flutter/material.dart';
class TweetsListPage extends StatefulWidget {
@override
State createState() => TweetListState();
}
class TweetListState extends State
with AutomaticKeepAliveClientMixin {
@override
Widget build(BuildContext context) {
return Center(
child: Text('TweetsListPage'),
);
}
@override
void dispose() {
print('TweetsListPage dispose');
super.dispose();
}
// 当页面不显示的时候也常驻在内存中
@override
bool get wantKeepAlive => true;
}
有时候我们需要手动的改变当前显示的tab , 这时候就需要自己创建一个controller了 ,
TabController tabController;
@override
void initState() {
// TODO: implement initState
super.initState();
tabController = TabController(length: myTabs.length, vsync: this);
}
这时, 我们外面套用的 DefaultTabController 就可以去掉了 , 它的作用就是当我们没写controller的时候使用的 , 因为tabbar以及tabbarView是必须有个controller的.
执行
tabController.animateTo(index)
就会跳转到对应的tab , 当然 要在tabBar 以及tabbarView 中都设置controller .
炫酷版:
代码: github