可滚动页面中的 TabBarView

TabBarView within Scrollable Page

我很难让布局在 Flutter 中工作。

我正在尝试创建的布局:

这是布局示意图:

示例代码

这是一个最简单的示例代码(删除了确切的小部件定义):

return DefaultTabController(
      length: 2,
      child: ListView(
        children: [
          // TOP CONTAINER //
          Container(height: 30),

          // TAB BAR //

          const TabBar(tabs: [
            Tab(child: Text("Tab 1")),
            Tab(child: Text("Tab 2")),
          ]),

          // TAB BAR VIEWS //
          SizedBox(
            height: MediaQuery.of(context).size.height,
            child: TabBarView(
              children: [
                Container(height: 5000),
                Container(height: 5000),
              ],
            ),
          )
        ],
      ),
    );

问题:

当window的高度变小时,底部出现溢出错误:

我做了什么:

  • 我首先尝试将内部 Column 转换为 ListView,这修复了溢出,但导致了两个单独的可滚动区域(单个选项卡视图和整个页面),这不是我想要的 - 我想要一个单一的可滚动区域。将此 ListViewphysics 属性 设置为 NeverScrollablePhysics() 并不能解决此问题并导致一些奇怪的行为。
  • 我尝试使用 NestedScrollViewSilvers(来自 )。但这会导致在选项卡中导航时出现以下异常:The provided ScrollController is currently attached to more than one ScrollPosition.,并产生一些不可靠的滚动机制。
  • 我尝试使用 CustomScrollView,但没有用。

没有提供有效解决方案的类似问题:

  • how to implement a sliverAppBar with a tabBar

我很困惑为什么它不起作用,因为我觉得这是一件非常简单的事情。本质上,它与 Instragram 应用程序(以及其他应用程序)在查看您的个人资料时使用的布局相同(参见:https://unblast.com/wp-content/uploads/2020/01/Instagram-UI-Profile-1.jpg)。

根据评论,您可以将页面包装在 singlechildscrollview 中,禁用列表视图的滚动物理,因为父级已经可以滚动。

return SIngleChildScrollView(child: DefaultTabController(
      length: 2,
      child: ListView(
physics:NeverScrollablePhysics(),
        children: [
          // TOP CONTAINER //
          Container(height: 30),

          // TAB BAR //

          const TabBar(tabs: [
            Tab(child: Text("Tab 1")),
            Tab(child: Text("Tab 2")),
          ]),

          // TAB BAR VIEWS //
          SizedBox(
            height: MediaQuery.of(context).size.height,
            child: TabBarView(
              children: [
                Container(height: 5000),
                Container(height: 5000),
              ],
            ),
          )
        ],
      ),
    ));

** 选项 2 **

您可以使用 customScrollViewnestedScrollView

DefaultTabController(
      length: 2,
      child:
CustomScrollView(
              slivers: [

SlivertoboxAdapter(child:   // TOP CONTAINER //
          Container(height: 30),

SlivertoboxAdapter(child:   // TAB BAR //

          const TabBar(tabs: [
            Tab(child: Text("Tab 1")),
            Tab(child: Text("Tab 2")),
          ]),

//... Sliverfillremaining/slivettoboxadapter for your tabbarview

SlivertoboxAdapter(child:TabBarView(
              children: [
                Container(height: 5000),
                Container(height: 5000),
              ],
            ),