I am having real trouble getting a layout to work within Flutter.
The layout I am trying to create:
ListView
that contains a:
Container
.TabBar
.TabBarView
, where each TabBarView
contains a Column
.Here is the schematic for the layout:
Example Code
Here is a minimum example code (with exact widget definitions removed):
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),
],
),
)
],
),
);
The Problem:
When the height of the window gets smaller, I get an overflow error at the bottom:
What I have Done:
Column
into a ListView
, which fixed the overflow, but resulted in two separate scrollable areas (the individual tab views and the whole page), which is not what I want - I want a single scrollable area. Setting the physics
property of this ListView
to NeverScrollablePhysics()
doesnt fix this and results in some weird behaviour.NestedScrollView
with Silvers
(from How to create a bounded scrollable TabBarView). But this results in the following exception when navigating through the tabs: The provided ScrollController is currently attached to more than one ScrollPosition.
, and produces some dodgy scroll mechanics.CustomScrollView
but that didnt work.Similar Questions that Didnt provide a working solution:
I am very confused as to why it is not working as I feel this is a very simple thing. Essentially, it is the same layout used in the Instragram app (among others) when viewing your personal profile (see: https://unblast.com/wp-content/uploads/2020/01/Instagram-UI-Profile-1.jpg).
From the comments you can wrap your page in a singlechildscrollview
, disable scroll physics for the listview as the parent is already scrollable.
return SingleChildScrollView(
child: DefaultTabController(
length: 2,
child: ListView(
physics: NeverScrollableScrollPhysics(),
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),
],
),
)
],
),
));
** Option2 **
you can use a customScrollView
or a nestedScrollView
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),
],
),