颤振片可以具有不同的宽度,并且可以将剩余空间均匀分配为左右填充物吗?

这是我尝试执行的方法,但是我显然需要以某种方式计算填充。我正在考虑在最坏的情况下创建某种函数来计算所有这些,但是我可以选择元素并获取值吗?

这大致就是我希望它们的外观(之间的间距应根据屏幕尺寸而变化)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',],)),
hyklq 回答:颤振片可以具有不同的宽度,并且可以将剩余空间均匀分配为左右填充物吗?

TabBar的实现方式不允许设置灵活的标签。因此,您必须计算每个标签的水平填充。

您需要获取制表符宽度,以便执行此操作:

  • 为每个GlobalKey设置一个Tab,然后访问 key.currentContext.size.width
  • 由于key.currentContext在构建期间为null,因此您需要 等待呈现TabBar,然后获取制表符的宽度。去做 您可以使用WidgetsBinding.instance.addPostFrameCallback() 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,);
  }
}

您可以这样使用它:

@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',],)
    ),);
}

注意:

  • TabBar如果不适合屏幕宽度,将可以滚动。
  • 检查// TODO: pass other parameters used in the TabBar received
  • 如果要使用DefaultTabController,则可能需要删除 自定义的。
本文链接:https://www.f2er.com/3136796.html

大家都在问