答案 0 :(得分:1)
TabBar
中提供了一些基本属性,但是在您的用例中还不够。
您必须创建一个TabController
和一个索引变量。每当发生切换时,TabController
都必须设置索引,并且必须根据该索引设置标签的背景。
编辑代码以通过边界半径进一步优化答案
示例代码
class _TabDemoState extends State<TabDemo> with SingleTickerProviderStateMixin {
TabController _tabController;
int _selectedTab = 0;
@override
void initState() {
super.initState();
_tabController = TabController(vsync: this, length: 3);
_tabController.addListener((){
if (!_tabController.indexIsChanging){
setState(() {
_selectedTab = _tabController.index;
});
}
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("Tab Demo"),
),
backgroundColor: Colors.white,
body: DefaultTabController(
length: 3,
child: Column(
children: <Widget>[
Material(
color: Colors.grey.shade300,
child: TabBar(
unselectedLabelColor: Colors.blue,
labelColor: Colors.blue,
indicatorColor: Colors.white,
controller: _tabController,
labelPadding: const EdgeInsets.all(0.0),
tabs: [
_getTab(0, Icon(Icons.directions_car)),
_getTab(1, Icon(Icons.directions_transit)),
_getTab(2, Icon(Icons.directions_bike)),
],
),
),
Expanded(
child: TabBarView(
physics: NeverScrollableScrollPhysics(),
controller: _tabController,
children: [
Icon(Icons.directions_car),
Icon(Icons.directions_transit),
Icon(Icons.directions_bike),
],
),
),
],
)),
);
}
_getTab(index, child) {
return Tab(
child: SizedBox.expand(
child: Container(
child: child,
decoration: BoxDecoration(
color:
(_selectedTab == index ? Colors.white : Colors.grey.shade300),
borderRadius: _generateBorderRadius(index)),
),
),
);
}
_generateBorderRadius(index) {
if ((index + 1) == _selectedTab)
return BorderRadius.only(bottomRight: Radius.circular(10.0));
else if ((index - 1) == _selectedTab)
return BorderRadius.only(bottomLeft: Radius.circular(10.0));
else
return BorderRadius.zero;
}
}
注意-在此过程中,我遇到了一个问题。当您从左向右快速滑动_tabContoller
值时,它首先返回两个值,它给您的index-2
值比预期的index-1
值大。我不知道为什么会这样,但是要解决此问题,我必须禁用TabBarView
上的滚动。