I'm Terrence

Flutter: tabBar一定要居中吗?

提问

flutter 的 tabbar 都是这个样子居中的,

能不能不居中呢?
一开始对了下那 tabbar api 中的几个属性,

const TabBar({
Key key,
@required this.tabs,
this.controller,
this.isScrollable = false,
this.indicatorColor,
this.indicatorWeight = 2.0,
this.indicatorPadding = EdgeInsets.zero,
this.indicator,
this.indicatorSize,
this.labelColor,
this.labelStyle,
this.labelPadding,
this.unselectedLabelColor,
this.unselectedLabelStyle,
this.dragStartBehavior = DragStartBehavior.start,
this.onTap,}
) 

发现通过设置属性是不能达到预想效果,于是,弱弱地走去了人家官网提了个 issue, can tabBar not centered ? 过了几天,flutter 工程师还加了个这样标签 f: material design framework ,相当于承认了这个问题?哈哈

自问自答

isScrollable 这个属性默认是 false 的,把他设成 isScrollable = true 后,发现到有个细节改变了,由原来充满这一行的的表现,变成“收敛”了。

既然每个 tab 都收敛了,那么现在只剩下一个问题了:如何把整个 tabBar 向左对齐?

我第一个想到的是,把 tabBar 用个 container 包裹着,设置下 alignment 不就行了?

Container(
      alignment: Alignment.topLeft,
      child: TabBar(
        labelColor: Colors.black,
        isScrollable: true,
        labelStyle: TextStyle(fontSize: 15, fontWeight: FontWeight.bold),
        unselectedLabelColor: Colors.grey,
        unselectedLabelStyle: TextStyle(fontSize: 11),
        controller: _tabController,
        tabs: tabs.map((e) => Tab(text: e)).toList(),
      ),
    )

是的,指定alignment: Alignment.topLeft这样就可以实现这种效果了

延伸

如果需要放在 Scaffold.appBar 里面的话,则需要额外实现 PreferredSizeWidget 这个接口,PreferredSize 这个 widget 就实现了这个接口,我们用 PreferredSize 再包一层,即可。

这里注意一下,preferredSize 这个属性, 并不是用来约束他的 child, 而是当这个组件本身没有设置任何约束时,对自己大小的一种声明。也就是说,如果外部对其是有约束的话,这个属性是用不着的。

/// The size this widget would prefer if it were otherwise unconstrained.
/// A widget with a preferred size.
///
/// This widget does not impose any constraints on its child, and it doesn’t
/// affect the child’s layout in any way. It just advertises a preferred size
/// which can be used by the parent.