无法在颤振中为 TabBarView 设置动态高度

zil*_*nas 10 tabbar dart flutter

我正在尝试创建位于页面中间的 TabBar(说明小部件必须位于顶部)。

问题是我必须手动设置包含 TabBarView 的容器小部件的高度。如果我离开它没有这个高度,我会得到错误Horizontal viewport was given unbounded height.

顶级小部件:

  Widget build(BuildContext context) {
    return Scaffold(
      appBar: CustomAppBar(),
      body: SingleChildScrollView(
        child: Column(
          children: <Widget>[Description(), Tabs()],
        ),
      ),
    );
  }
Run Code Online (Sandbox Code Playgroud)

标签小部件:

class Tabs extends StatelessWidget {
  final _tabs = [
    Tab(
      icon: Icon(Icons.menu),
      text: 'Menu',
    ),
    Tab(
      icon: Icon(Icons.mode_comment),
      text: 'Reviews',
    )
  ];

  @override
  Widget build(BuildContext context) {
    return DefaultTabController(
        length: _tabs.length,
        child: Column(
          children: <Widget>[
            TabBar(
              labelColor: PickColors.black,
              indicatorSize: TabBarIndicatorSize.tab,
              tabs: _tabs,
            ),
            Container(
              width: double.infinity,
              height: 200, // I need to remove this and make height dynamic
              child: TabBarView(
                children: <Widget>[MenuTab(), ReviewsTab()],
              ),
            ),
          ],
        ));
  }
}
Run Code Online (Sandbox Code Playgroud)

由于标签内容将是动态的,因此高度也将是动态的。我不能在这里使用静态高度。

具有静态高度的 Container 是否有替代方案?如何使标签的高度动态化?

zil*_*nas 3

我通过将 SingleChildScrollView 更改为 ListView 并编写自己的 TabView 小部件(其中包含 Stack 包装器中的选项卡)解决了此问题。

顶级小部件主体包装从 Column 和 SingleChildScrollView 更改为 ListView:

  Widget build(BuildContext context) {
    SizeConfig().init(context);
    return Scaffold(
      appBar: RestaurantInfoAppBar(),
      body: ListView(
        children: <Widget>[Description(), Tabs()],
      ),
    );
  }
Run Code Online (Sandbox Code Playgroud)

选项卡小部件 - 删除了带有静态宽度包装器的容器:

  Widget build(BuildContext context) {
    return DefaultTabController(
        length: _tabs.length,
        child: Column(
          children: <Widget>[
            TabBar(
              labelColor: PickColors.black,
              indicatorSize: TabBarIndicatorSize.tab,
              tabs: _tabs,
            ),
            TabsView(
              tabIndex: _tabIndex,
              firstTab: MenuTab(),
              secondTab: ReviewsTab(),
            )
          ],
        ));
  }
Run Code Online (Sandbox Code Playgroud)

新的自定义 TabsView 组件当前仅处理两个选项卡(因为我只需要两个),但可以轻松更改以处理动态数量的选项卡:

class TabsView extends StatelessWidget {
  TabsView(
      {Key key,
      @required this.tabIndex,
      @required this.firstTab,
      @required this.secondTab})
      : super(key: key);

  final int tabIndex;
  final Widget firstTab;
  final Widget secondTab;

  @override
  Widget build(BuildContext context) {
    return Stack(
      children: <Widget>[
        AnimatedContainer(
          child: firstTab,
          width: SizeConfig.screenWidth,
          padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 24),
          transform: Matrix4.translationValues(
              tabIndex == 0 ? 0 : -SizeConfig.screenWidth, 0, 0),
          duration: Duration(milliseconds: 300),
          curve: Curves.easeIn,
        ),
        AnimatedContainer(
          child: secondTab,
          width: SizeConfig.screenWidth,
          padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 24),
          transform: Matrix4.translationValues(
              tabIndex == 1 ? 0 : SizeConfig.screenWidth, 0, 0),
          duration: Duration(milliseconds: 300),
          curve: Curves.easeIn,
        )
      ],
    );
  }
}
Run Code Online (Sandbox Code Playgroud)

PS SizeConfig 与 MediaQuery.of(context).size.width 相同。

希望这对像我这样的人有帮助!:)

  • TabsView 占据了内容较大的选项卡的高度,因此内容较少的另一个选项卡有一个空白空间。有什么办法解决吗? (3认同)