[英]Add bottom border of to tabs in Flutter
What I'm trying to do is adding a bottom border of tabBar, so it will be under tabs title and above the indicatorColor and for both active and Inactive tabs, just like the attached image.我想要做的是添加 tabBar 的底部边框,因此它将位于选项卡标题下方和指示器颜色上方以及活动和非活动选项卡,就像附加的图像一样。
Red line is what I am trying to add, green line is the indicatorColor.红线是我要添加的,绿线是指标颜色。
Note, usually I do this for appBar using 'bottom' but here bottom is reserved to the TabBar .请注意,通常我使用 'bottom' 为 appBar 执行此操作,但这里的底部保留给 TabBar 。
Is this possible?这可能吗?
Thanks a lot非常感谢
Try to set appBar border :尝试设置 appBar 边框:
appBar: AppBar(
shape: Border(bottom: BorderSide(color: Colors.red)),
....
You can set the AppBar shape
property as abdulrahmanAbdullah says.您可以像 abdulrahmanAbdullah 所说的那样设置 AppBar
shape
属性。 But if you strictly need the border above the indicator, you can put it inside of each tab bar item.但是,如果您严格需要指示器上方的边框,则可以将其放在每个选项卡栏项目内。 Here's one take on it:
这是一个看法:
import 'package:flutter/material.dart';
void main() {
runApp(TabBarDemo());
}
class TabBarDemo extends StatelessWidget {
Widget _createTab(String text) {
return Tab(
child: Row(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
Expanded(
child: Container(
child: Center(child: Text(text)),
decoration: BoxDecoration(border: Border(bottom: BorderSide(color: Colors.black)))
)
),
]
),
);
}
@override
Widget build(BuildContext context) {
return MaterialApp(
theme: ThemeData(
primaryColor: Colors.white,
),
home: DefaultTabController(
length: 3,
child: Scaffold(
appBar: AppBar(
elevation: 0,
bottom: TabBar(
labelPadding: EdgeInsets.all(0),
tabs: [
_createTab("Tab 1"),
_createTab("Tab 2"),
_createTab("Tab 3"),
],
),
title: Text('Tabs Demo'),
),
body: TabBarView(
children: [
Icon(Icons.directions_car),
Icon(Icons.directions_transit),
Icon(Icons.directions_bike),
],
),
),
),
);
}
}
I managed to do that using ' flexibleSpace ' property instead 'bottom' property, as flexibleSpace can have any widget not only 'PreferredSizeWidget' like bottom.我设法使用“灵活空间”属性而不是“底部”属性来做到这一点,因为灵活空间可以拥有任何小部件,而不仅仅是像底部这样的“PreferredSizeWidget”。
So I gave a Column to the flexibleSpace, then I was able to put TabBar and the container inside that column, then using Matrix4.translationValues(0.0, -2.6, 0.0) I gave the container, which contain the border, a nigative-padding(or similar) so it moved to the top of the indicatorColor.所以我给了一个 Column 给了 flexibleSpace,然后我可以把 TabBar 和容器放在那个列中,然后使用 Matrix4.translationValues(0.0, -2.6, 0.0) 我给了包含边框的容器,一个 nigative-padding (或类似的)所以它移到了 indicatorColor 的顶部。
return SafeArea(
top: true,
child: Scaffold(
appBar: PreferredSize(
preferredSize: Size.fromHeight(100.0),
child: AppBar(
backgroundColor: Theme.of(context).buttonColor,
title: Text(
'AppBar',
textAlign: TextAlign.center,
style: Theme.of(context).textTheme.title,
),
centerTitle: true,
elevation: 0.0,
flexibleSpace: Padding(
padding: const EdgeInsets.only(top: 50.0),
child: Column(
children: <Widget>[
// Tab Bar
new TabBar(
indicatorColor: Theme.of(context).accentColor,
tabs: <Tab>[
new Tab(
text: 'Tab1',
),
new Tab(
text: 'Tab2',
),
],
controller: _tabController,
),
// Border
Container(
// Negative padding
transform: Matrix4.translationValues(0.0, -2.6, 0.0),
// Add top border
decoration: BoxDecoration(
border: Border(
top: BorderSide(
color: Color(0xFFc3c3c3),
width: 0.6,
),
),
),
),
],
),
),
),
),
body: new TabBarView(
children: <Widget>[
new Tab1(),
new Tab2(),
],
controller: _tabController,
),
),
);
And the magic happened ^^奇迹发生了^^
Here's my version of spenster's solution ;这是我的spenster 解决方案版本;
Instead of a function, I created a new widget "BorderedTab" which implements Tab:我创建了一个实现 Tab 的新小部件“BorderedTab”,而不是一个函数:
import 'package:flutter/material.dart';
class BorderedTab extends StatelessWidget implements Tab {
const BorderedTab({
Key key,
this.text,
this.borderColor=Colors.grey,
this.width=0.5,
}) : super(key: key);
final String text;
final Color borderColor;
final double width;
@override
Widget build(BuildContext context) {
return Tab(
child: Row(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
Expanded(
child: Container(
child: Center(
child: Text(text)
),
decoration: BoxDecoration(
border: Border(
bottom: BorderSide(
width: width,
color: borderColor,
),
),
),
),
),
]
),
);
}
@override
// TODO: implement child
Widget get child => null;
@override
// TODO: implement icon
Widget get icon => null;
}
then I used BorderedTab just like the regular Tab, but with:然后我像使用常规 Tab 一样使用 BorderedTab,但具有:
labelPadding: EdgeInsets.all(0.0), // Important to remove default padding
Final AppBar:最终应用栏:
import 'package:../widgets/bordered_tab.dart';
...
appBar: AppBar(
backgroundColor: Theme.of(context).buttonColor,
title: Text(
'TabBar',
textAlign: TextAlign.center,
style: Theme.of(context).textTheme.title,
),
centerTitle: true,
elevation: 0.0,
bottom: new TabBar(
labelColor: Theme.of(context).primaryColor,
indicatorColor:Theme.of(context).accentColor,
labelPadding: EdgeInsets.all(0.0), // Important to remove default padding
tabs: <Tab>[
BorderedTab(
text: 'Tab1',
borderColor: Color(0xFFc3c3c3),
),
BorderedTab(
text: 'Tab2',
borderColor: Color(0xFFc3c3),
),
],
controller: _tabController,
),
),
Another approach is to use a stack and place the line underneath the tabs另一种方法是使用堆栈并将线放置在选项卡下方
Stack(
alignment: Alignment.bottomCenter,
children: [
Container(
decoration: BoxDecoration(
border: Border(
bottom: BorderSide(color: Colors.white70, width: 1),
)),
),
TabBar(
indicatorWeight: 3.0,
tabs: [
Tab(
icon: Icon(Icons.home),
),
Tab(
icon: Icon(Icons.show_chart),
),
],
),
],
),
Simply you can wrap TabBar into DecoratedBox as below:简单地,您可以将TabBar包装到DecoratedBox 中,如下所示:
DecoratedBox(
decoration: BoxDecoration(
//This is for background color
color: Colors.white.withOpacity(0.0),
//This is for bottom border that is needed
border: Border(
bottom: BorderSide(color: AppColors.color4, width: 2.sp)),
),
child: TabBar(
...
),
),
Hope you will get help.希望你能得到帮助。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.