Flutter TabBarView 子项因高度无限制无法渲染

Flutter TabBarView Children Unable to Render Due to Unbounded Height

我正在尝试复制以下设计:

https://lh3.googleusercontent.com/pOGNNz2MYFZg24jd7Yf55mLXFRWIYMCNQSUshnPX6P2iYsMQn8bkezdp8tQD-Y9GcD0=w2560-h1370

我似乎不明白为什么 TabBarView 中的子窗口小部件会导致异常。提到了无限高度,但我提供了子部件的高度和宽度,所以我对发生了什么感到困惑...

仅供参考:TripPage 小部件(未在代码中显示,仅显示其状态)作为值传递给 Scaffold 的 body 属性(也未显示)。我不想改变这个。

这是我的代码:

class _TripPageState extends State<TripPage> {
  //ToDo: Keep as dynamic until an object is created for the listItems.
  List<dynamic> upcomingTrips;
  List<dynamic> pastTrips;

  Widget build(BuildContext context) {
    return Column(
      children: <Widget>[
        Row(mainAxisAlignment: MainAxisAlignment.start, children: <Widget>[
          Padding(
            child: Text(
              "Trips",
              style: TextStyle(
                  color: Colors.deepPurple,
                  fontSize: 36.0,
                  fontWeight: FontWeight.bold),
            ),
            padding: EdgeInsets.only(top: 40.0, left: 28.0),
          )
        ]),
        DefaultTabController(
          length: 2,
          child: Column(mainAxisSize: MainAxisSize.max, children: <Widget>[
            Padding(
                padding: EdgeInsets.only(left: 16.0, top: 24.0),
                child: Row(children: <Widget>[
                  TabBar(
                    tabs: <Widget>[
                      Tab(text: "Upcoming".toUpperCase()),
                      Tab(text: "Past".toUpperCase())
                    ],
                    isScrollable: true,
                    indicatorColor: Colors.deepPurple,
                    labelColor: Colors.black,
                    unselectedLabelColor: Color.fromRGBO(78, 78, 81, 30),
                  )
                ])),
            TabBarView(
              children: <Widget>[
                Container(
                    color: Colors.pink,
                    child: Image.asset('assets/saved_flights_icon.jpg',
                        width: 200.0, height: 200.0)),
                Container(
                    color: Colors.greenAccent,
                    child: Image.asset('assets/saved_flights_icon.jpg',
                        width: 200.0, height: 200.0)),
//                UpcomingTripsTabPage(),
//                PastTripsTabPage()
              ],
            )
          ]),
        )
      ],
    );
  }
}

但是我的堆栈跟踪中出现以下消息:

I/flutter ( 7054): The following assertion was thrown during performResize():
I/flutter ( 7054): Horizontal viewport was given unbounded height.
I/flutter ( 7054): Viewports expand in the cross axis to fill their container and constrain their children to match
I/flutter ( 7054): their extent in the cross axis. In this case, a horizontal viewport was given an unlimited amount of
I/flutter ( 7054): vertical space in which to expand.

后面有几条关于 RenderBoxesRenderViewports 等的消息

提前致谢!

我认为您需要将 TabBarView 包装在容器中并为其提供高度。

              Container(
                height: 200.0,
                child: TabBarView(
                  children: <Widget>[
                    Container(
                        color: Colors.pink,
                        child: Image.asset('assets/saved_flights_icon.jpg',
                            width: 200.0, height: 200.0)),
                    Container(
                        color: Colors.greenAccent,
                        child: Image.asset('assets/saved_flights_icon.jpg',
                            width: 200.0, height: 200.0)),
//                UpcomingTripsTabPage(),
//                PastTripsTabPage()
                  ],
                ),
              )

简答:

要使用 TabBarView,您应该提供一个有限的高度。有几种方法可以做到这一点。其中之一是将它包装在一个高度受限的小部件中(例如,ContainerSizedBox)。或者,如果小部件的父级具有受限尺寸(在您的情况下它没有),您可以将 TabBarView 包装在 Expanded 小部件中,这将指示它扩展以填充可用的 space.

对于您的情况,类似以下内容应该可以解决问题:

Container( // or SizedBox, etc.
  height: 200
  child: TabBarView(...)
)

背景:

您正在使用没有任何高度限制的 TabBarView 视图。换句话说,它的高度是无限的,如错误所示:

Horizontal viewport was given unbounded height.

Viewports expand in the cross axis to fill their container and constrain their children to match their extent in the cross axis. In this case, a horizontal viewport was given an unlimited amount of vertical space in which to expand.

要了解 unbounded(和其他术语)在此上下文中的确切含义,我们可以参考 BoxConstraints class:

An axis whose maximum constraint is infinite is unbounded.

因此,我们可以看到在某些情况下小部件被赋予无限的最大高度(垂直 space)以用于扩展。如果小部件试图填充所有可用的(无限)space,这将证明是有问题的。因此,Flutter 会抛出一个错误。这可以通过将小部件包装在具有约束 width/height.

的父级中来约束小部件来解决

可以在 documentation:

In certain situations, the constraint that is given to a box is unbounded, or infinite. This means that either the maximum width or the maximum height is set to double.INFINITY.

A box that tries to be as big as possible won’t function usefully when given an unbounded constraint and, in debug mode, such a combination throws an exception that points to this file.

如果你有兴趣,你可以看看错误的来源here