I am trying to replicate the following design:
I don't seem to understand why the child widgets within my TabBarView
are causing an exception. There is a mention of unbounded height but I have provided the height and width of the child widgets so I'm confused as to what's going on...
FYI: the TripPage
widget (not shown in the code, only its state is) is passed as the value to the body attribute of a Scaffold
(also not shown). I don't want to change this.
Here is my code:
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()
],
)
]),
)
],
);
}
}
However I get the following message appearing on my stack trace:
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.
Followed by several messages about RenderBoxes
, RenderViewports
, etc.
Thanks in advance!
Short answer:
To use TabBarView
you should provide a finite height. There are a few ways to do it. One of them is to wrap it in a widget with a constrained height (e.g., Container
or SizedBox
). Alternatively, if the parent of a widget has constrained dimensions (in your case it has not), you could wrap TabBarView
in an Expanded
widget which would instruct it to expand to fill the available space.
For your case something like the following should solve the issue:
Container( // or SizedBox, etc.
height: 200
child: TabBarView(...)
)
Background:
You're using TabBarView
view which does not have any height constraints. In other words, its height is unbounded, as suggested by the error:
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.
To understand what exactly unbounded (and other terminology) means in this context, we can refer to BoxConstraints
class:
An axis whose maximum constraint is infinite is unbounded.
Hence, we can see that in certain cases widgets are given infinite maximum height (vertical space) to use for expansion. If a widget tries to fill all available (infinite) space this will prove to be problematic. Therefore, Flutter throws an error. This can be fixed by constraining the widget by wrapping it in a parent with a constrained width/height.
A rather instructive (although somewhat short) explanation of what is happening can be found in the 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.
If you're interested, you can see where the origin of an error here.