我正在尝试使用 PreferredSize 创建自定义 TabBar,但我无法将 TabBar 的颜色与我的正文融合,TabBar 和正文之间似乎有边框。下图将清楚地向您展示我正在努力实现的目标。
我尝试创建一个与主体颜色相同且宽度较大的边框,但似乎不起作用。这是我的代码:
Widget _buildAppBar(context) {
return AppBar(
title: Text(title),
elevation: 0,
flexibleSpace: Image.asset(
'images/motif_batik_01.jpg',
fit: BoxFit.cover,
width: 1200,
),
bottom: _buildTabBar(context)
);
}
Widget _buildTabBar(context) {
return PreferredSize(
preferredSize: Size.fromHeight(100.0),
child: Container(
decoration: BoxDecoration(
color: Theme.of(context).backgroundColor,
borderRadius: BorderRadius.only(
topLeft: Radius.circular(50),
topRight: Radius.circular(50),
),
),
padding: EdgeInsets.only(
top: 50,
left: 20,
right: 20,
),
height: 100,
child: TabBar(
indicator: BoxDecoration(
color: Colors.orange, borderRadius: BorderRadius.circular(20)
),
labelStyle: TextStyle(color: Colors.white),
unselectedLabelColor: Colors.orange,
tabs: <Widget>[
Tab(child: Text('A', style: TextStyle(fontSize: 18.0))),
Tab(child: Text('B', style: TextStyle(fontSize: 18.0))),
],
),
)
);
}
编辑注释:我发现如果我的“preferedSize”是 40.0 (40.0, 80.0) 的乘积,该线就会消失,这可能是颤振本身的一个错误吗?
如果您在应用程序中使用 Material3,事情会变得很糟糕:
ThemeData(
useMaterial3: true,
...
)
那么所有提到的解决方案都不起作用。如果我们阅读
TabBar
的文档:
/// The color of the divider.
///
/// If null and [ThemeData.useMaterial3] is true, [TabBarTheme.dividerColor]
/// color is used. If that is null and [ThemeData.useMaterial3] is true,
/// [ColorScheme.surfaceVariant] will be used, otherwise divider will not be drawn.
final Color? dividerColor;
所以即使我们做了一些技巧,应用程序也会选择
TabBarTheme.dividerColor
。我尝试将其设置为 null
或 Colors.Transparent
,但没有成功。因此,它引导我尝试使用ColorScheme.surfaceVariant
。
解决方案之一是为您的
Widget
创建此主题包装(父Widget
):
@override
Widget build(BuildContext context) {
var theme = Theme.of(context);
return Theme(
data: theme.copyWith(
colorScheme: theme.colorScheme.copyWith(
surfaceVariant: Colors.transparent,
),
),
child: TabBar(
...
)
);
}
为 tabBar 添加指示器颜色,颜色为透明。
indicatorColor: Colors.transparent
indicator:BoxDecoration()
或者
indicatorColor:Colors.transparent
为 tabBar 添加分隔线颜色,并将颜色设置为透明。
dividerColor: Colors.transparent
添加此行:
`dividerColor: Colors.transparent,`
在 TabBar() 内然后热重载。
无论您在
body
中返回什么,请将其包装在下面的代码中。不要忘记关闭括号。
MediaQuery.removePadding(
context: context,
removeTop: true,
如果你使用的是material3,那么你可以使用这个:
indicator: const UnderlineTabIndicator(borderSide: BorderSide.none)
您可以设置
indicatorWeight: 0
。这样就可以了。
添加以下属性。
indicatorColor: Colors.transparent,
indicatorPadding: EdgeInsets.zero,
indicatorWeight: double.minPositive,
示例:
TabBar(
tabs: widget.tabs
.mapIndexed((index, e) => _buildTabItem(tab: e, index: index))
.toList(),
controller: widget.controller,
labelPadding: EdgeInsets.zero,
indicatorColor: Colors.transparent,
indicatorPadding: EdgeInsets.zero,
indicatorWeight: double.minPositive,
physics: const ClampingScrollPhysics(),
)
TabBar(dividerColor: Colors.transparent,)
在 Themedata 将 useMaterial3 更改为 false ,它对我有用
useMaterial3: false,
使
dividerColor: Colors.transparent
发挥作用。
Widget build(BuildContext context) {
return DefaultTabController(
length: 2,
child: Scaffold(
appBar: AppBar(
title: TopBarDownloads(toptitle: 'New & Hot'),
automaticallyImplyLeading: false,
bottom: TabBar(
isScrollable: true,
dividerColor: Colors.transparent,
indicatorSize: TabBarIndicatorSize.tab,
unselectedLabelColor: Colors.white,
indicator: BoxDecoration(
borderRadius: kBordRadius(30),
color: Colors.white
),
tabs: const [
Tab(text: '🍿 Coming Soon',),
Tab(text: '👀 Everyone\'s Watching',),
]
),
),
body: TabBarView(children: [
buildTabBarView('Coming Soon 🍿'),
buildTabBarView('Everyone\'s Watching')
]
)
),
);}
您是否尝试过将容纳 TabBar 的 AppBar 的高度设置为 0,
final topBar = AppBar(
elevation: 0.0, <------------ here
backgroundColor: Colors.white,
bottom: TabBar(
indicatorColor: Colors.black,
indicatorWeight: 2.0,
indicatorSize: TabBarIndicatorSize.tab,
tabs: [
Tab(
child: Text(
'Tab one',
style: headerTextStyle,
)),
Tab(
child: Text(
'Tab two',
style: headerTextStyle,
)),
],
),
);
añade estas propiedades al
TabBar( indicator: UnderlineTabIndicator(
insets: EdgeInsets.all(5),
),
indicatorWeight: 0,
indicatorSize: TabBarIndicatorSize.tab,
labelPadding: EdgeInsets.all(0), )