我想做的是添加 tabBar 的底部边框,因此它将位于选项卡标题下方、指示器颜色上方,对于活动选项卡和非活动选项卡,就像所附图像一样。
红线是我要添加的内容,绿线是指示器颜色。
注意,通常我使用“底部”为 appBar 执行此操作,但这里底部保留给 TabBar。
这可能吗?
非常感谢
您可以按照 abdulrahmanAbdullah 的说明设置 AppBar
shape
属性。但如果您严格需要指示器上方的边框,则可以将其放在每个选项卡栏项目内。这是对此的一种看法:
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),
],
),
),
),
);
}
}
尝试设置appBar边框:
appBar: AppBar(
shape: Border(bottom: BorderSide(color: Colors.red)),
....
只需将 TabBar 包装到 DecolatedBox 中,如下所示:
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(
...
),
),
希望您能得到帮助。
我设法使用'flexibleSpace'属性而不是'bottom'属性来做到这一点,因为flexibleSpace可以有任何小部件,而不仅仅是像bottom这样的'PreferredSizeWidget'。
所以我给了flexibleSpace一个列,然后我能够将TabBar和容器放入该列中,然后使用Matrix4.translationValues(0.0, -2.6, 0.0)我给了包含边框的容器,一个负数-填充(或类似),因此它移动到指标颜色的顶部。
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,
),
),
);
奇迹发生了^^
另一种方法是使用堆栈并将该行放置在选项卡下方
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),
),
],
),
],
),
这是我的 spenster 解决方案的版本;
我创建了一个新的小部件“BorderedTab”,它实现了 Tab:而不是函数:
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;
}
然后我像常规 Tab 一样使用 BorderedTab,但使用:
labelPadding: EdgeInsets.all(0.0), // Important to remove default padding
最终应用栏:
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,
),
),
我想添加一个答案
所有答案都有一个问题,就是底线要么高于指标,要么低于指标,而且高度也很难控制。
嗯。这是 flutter 3 中的工作版本
PreferredSize(
preferredSize: Size.fromHeight(kToolbarHeight),
child: DecoratedBox(
decoration: BoxDecoration(
border: Border(
bottom: BorderSide(
color: AppColors.border,
width: 3,
),
),
),
child: TabBar(
labelColor: AppColors.secondText,
unselectedLabelColor: AppColors.grayText,
indicator: UnderlineTabIndicator(
borderSide: BorderSide(
width: 3.0, color: AppColors.secondText),
insets: EdgeInsets.symmetric(horizontal: 30.0),
),
tabs: [
Tab(
text: "Tab 1",
),
Tab(
text: "Tab 2",
),
],
),
),
),
使用 DecoratedBox 和 PreferredSize
首先将 TabBar 放入 PreferredSize :
child: AppBar(
bottom: PreferredSize(
preferredSize: Size.fromHeight(50),
child: TabBar(
tabs: [
Tab(
text: 'tab-1',
),
Tab(
text: 'tab-2',
),
Tab(
text: 'tab-3',
),
],
),
),
),
然后用 DecoratedBox 包裹 TabBar
child: AppBar(
bottom: PreferredSize(
preferredSize: Size.fromHeight(50),
child: DecoratedBox(
decoration: BoxDecoration(
border: Border(bottom: BorderSide(width: 2,color: Color.fromARGB(255, 255, 0, 0)))
),
child: TabBar(
tabs: [
Tab(
text: 'tab-1',
),
Tab(
text: 'tab-2',
),
Tab(
text: 'tab-3',
),
],
),
),
),
),
不使用其他元素的最简单方法是将 BoxShadow 与 TabBar 一起使用,如下所示:
TabBar(
controller: _tabController,
indicator: BoxDecoration(
boxShadow: [
BoxShadow(
color: Colors.red,
offset: Offset(0, 2.0),
)
],
color: Colors.white,
),
labelColor: Colors.red,
unselectedLabelColor: Colors.grey.shade900,
labelPadding: EdgeInsets.symmetric(horizontal: 10.0),
isScrollable: false,
tabs: [
Tab(
text: 'T1',
),
Tab(
text: 'T2',
),
Tab(
text: 'T3',
),
Tab(
text: 'T4',
),
],
),
或者使用UnderlineTabIndicator作为TabBar的指示参数:
indicator: UnderlineTabIndicator(
borderSide: BorderSide(width: 3.0),
insets: EdgeInsets.symmetric(horizontal: 30.0),
),
您可以使用
TabBar
dividerColor
属性。