Reputation: 151
I would like to build a scrollable page which list different widgets (in a listview). Basically, my idea was to have the following setup:
SingleChildScrollView (Container (Column (... Expanded( ListView))))
This however only works with a fixed height for the container. Is there any way to dynamically change the height of the container depending how many widgets the listview displays?
PS: I made the listview non-scrollable as the overall page is already scrollable through SingleChildScrollView.
Hope someone can help here.
Thanks so much in advance, Nicolas
Code:
class _ProfileState extends State<Profile> {
@override
Widget build(BuildContext context) {
return SingleChildScrollView(
child: Container(height: 2000, child:
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Expanded(child: PostList()),
],),),);}}
And:
class _PostListState extends State<PostList> {
@override
Widget build(BuildContext context) {
final postData = Provider.of<List<PostData>>(context) ?? [];
if (postData != null) {
return ListView.builder(
physics: const NeverScrollableScrollPhysics(),
itemCount: postData.length,
itemBuilder: (context, index) {
return PostTile (postData: postData[index]);
},);
} else {
return Text('loading'); // Check if necessary
}}}
Upvotes: 0
Views: 1104
Reputation: 2014
In order to accomplish what you are looking for here, you should probably change the Listiew
into a Column
and remove the Container
.
Something like this:
class _ProfileState extends State<Profile> {
@override
Widget build(BuildContext context) {
return SingleChildScrollView(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
PostList(),
],),);}}
class _PostListState extends State<PostList> {
@override
Widget build(BuildContext context) {
final postData = Provider.of<List<PostData>>(context) ?? [];
if (postData != null) {
return Column(
children: ...postData.map((el) => PostTile (postData: el))
);
} else {
return Text('loading'); // Check if necessary
}}}
Upvotes: 1
Reputation: 496
If you want to have a list of different ListView
, try putting shrinkWrap: true
to all your listView
children and add physics
to it.
ListView(
shrinkWrap: false,
physics: ClampingScrollPhysics(),
children: <Widget>[
Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisSize: MainAxisSize.min,
children: <Widget>[
ListView.builder(
itemCount: 3,
shrinkWrap: true,
physics: ClampingScrollPhysics(),
itemBuilder: (context, index) {
return ListTile(
title: Text(
'Item #$index',
));
},
),
ListView.builder(
itemCount: 6,
shrinkWrap: true,
physics: ClampingScrollPhysics(),
itemBuilder: (context, index) {
return ListTile(
leading: Icon(Icons.settings),
title: Text(
'SecondItem #$index',
));
},
),
ListView.builder(
itemCount: 6,
shrinkWrap: true,
physics: ClampingScrollPhysics(),
itemBuilder: (context, index) {
return ListTile(
dense: false,
trailing: Icon(Icons.settings),
title: Text(
'THIRD ITEM #$index',
),
subtitle: Text(
'This is third item number $index',
));
},
),
],
),
],
)
Upvotes: 1