这是我尝试这样做的方式,但我显然需要以某种方式计算填充。我正在考虑在最坏的情况下创建某种计算所有这些的函数,但是我可以选择元素并获取值吗?
这大致是我希望它们的样子(之间的空间应根据屏幕尺寸而变化)https://i.imgur.com/huhC9vn.png
我也在想,也许有些屏幕可能无法适应它,因为模拟的屏幕非常大,在这种情况下,我也在考虑设置最小填充尺寸并使其可滚动。
bottom: TabBar(
labelPadding: EdgeInsets.only(left: 8, right: 8),
isScrollable: true,
tabs: <Widget>[
Tab(
text: 'General',
),
Tab(
text: 'Financial',
),
Tab(
text: 'Experts & Participants',
),
],
)),
Run Code Online (Sandbox Code Playgroud)
实现的方式TabBar不允许设置灵活的选项卡。所以你必须计算每个选项卡的水平填充。
您需要获取标签宽度,因此您可以执行以下操作:
GlobalKey为 eachTab然后访问
key.currentContext.size.width。key.currentContext将null构建过程中,你需要等待,直到TabBar被渲染,然后得到的标签宽度。为此,您可以使用WidgetsBinding.instance.addPostFrameCallback()
inside initState。didChangeDependencies而不是
initState.setState以更新选项卡的填充。setState整个树,您可以将 放入
TabBar自定义StatefulWidget.TabBar应用程序中的任何内容执行此操作,您可以创建一个自定义TabBar小部件,该小部件接收TabBar并返回一个带有计算填充的新小部件。因此,根据您的情况,您可以实施部分或全部提到的要点。这是一个包含所有提到的要点的示例:
class TabBarWithFlexibleTabs extends StatefulWidget implements PreferredSizeWidget {
TabBarWithFlexibleTabs({this.child});
final TabBar child;
@override
Size get preferredSize => child.preferredSize;
@override
_TabBarWithFlexibleTabsState createState() => _TabBarWithFlexibleTabsState();
}
class _TabBarWithFlexibleTabsState extends State<TabBarWithFlexibleTabs> {
final _tabs = <Widget>[];
final _tabsKeys = <Tab, GlobalKey>{};
var _tabsPadding = 0.0;
void _updateTabBarPadding() => setState(() {
final screenWidth = MediaQuery.of(context).size.width;
final tabBarWidth = _tabsKeys.values
.fold(0, (prev, tab) => prev + tab.currentContext.size.width);
_tabsPadding = tabBarWidth < screenWidth
? ((screenWidth - tabBarWidth) / widget.child.tabs.length) / 2
: widget.child.labelPadding?.horizontal ?? 16.0;
});
@override
void initState() {
super.initState();
widget.child.tabs.forEach((tab) => _tabsKeys[tab] = GlobalKey());
_tabs.addAll(widget.child.tabs
.map((tab) => Container(key: _tabsKeys[tab], child: tab)));
}
@override
void didChangeDependencies() {
super.didChangeDependencies();
WidgetsBinding.instance.addPostFrameCallback((_) => _updateTabBarPadding());
}
@override
Widget build(BuildContext context) {
return DefaultTabController(
length: widget.child.tabs.length,
child: TabBar(
tabs: _tabs,
isScrollable: true,
labelPadding: EdgeInsets.symmetric(
horizontal: _tabsPadding,
vertical: widget.child.labelPadding?.vertical ?? 0,
),
// TODO: pass other parameters used in the TabBar received, like this:
controller: widget.child.controller,
indicatorColor: widget.child.indicatorColor,
),
);
}
}
Run Code Online (Sandbox Code Playgroud)
你可以像这样使用它:
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
bottom: TabBarWithFlexibleTabs(
child: TabBar(
tabs: <Widget>[
Tab(
text: 'General',
),
Tab(
text: 'Financial',
),
Tab(
text: 'Experts & Participants',
),
],
),
)
),
);
}
Run Code Online (Sandbox Code Playgroud)
笔记:
TabBar如果它不能适应屏幕宽度,它将是可滚动的。// TODO: pass other parameters used in the TabBar received.DefaultTabController如果您想使用自定义的,您可能需要删除。| 归档时间: |
|
| 查看次数: |
1963 次 |
| 最近记录: |