【发布时间】:2019-08-02 20:39:40
【问题描述】:
我要做的是添加 tabBar 的底部边框,因此它将位于选项卡标题下方和 indicatorColor 上方,并且对于活动和非活动选项卡,就像附加的图像一样。
红线是我要添加的,绿线是指示器颜色。
注意,通常我使用“底部”为 appBar 执行此操作,但此处底部保留给 TabBar。
这可能吗?
非常感谢
【问题讨论】:
标签: android flutter dart flutter-layout
我要做的是添加 tabBar 的底部边框,因此它将位于选项卡标题下方和 indicatorColor 上方,并且对于活动和非活动选项卡,就像附加的图像一样。
红线是我要添加的,绿线是指示器颜色。
注意,通常我使用“底部”为 appBar 执行此操作,但此处底部保留给 TabBar。
这可能吗?
非常感谢
【问题讨论】:
标签: android flutter dart flutter-layout
尝试设置appBar边框:
appBar: AppBar(
shape: Border(bottom: BorderSide(color: Colors.red)),
....
【讨论】:
您可以按照 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),
],
),
),
),
);
}
}
【讨论】:
我设法使用 'flexibleSpace' 属性而不是 'bottom' 属性来做到这一点,因为 flexibleSpace 可以有任何小部件,而不仅仅是像底部这样的 'PreferredSizeWidget'。
所以我给了flexibleSpace一个Column,然后我能够将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,
),
),
);
奇迹发生了^^
【讨论】:
您只需将 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(
...
),
),
希望你能得到帮助。
【讨论】:
这是我的spenster's solution 版本;
我创建了一个新的小部件“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,
),
),
【讨论】:
另一种方法是使用堆栈并将行放在选项卡下方
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),
),
],
),
],
),
【讨论】: