Flutter ListView.builder() widget's cross Axis is taking up the entire Screen height
This question is similar to this: Flutter: Minimum height on horizontal list view
After digging around a bit, I've realized that a ListView may not be the widget you are looking for.
Prior to this, I showed that the only way to control the height of the ListView was through a fixed setting of height because that is what a ListView is designed to do - display a list of items that is pre-formatted.
If you want to have the same functionality where the children set the height instead, meaning the widget wraps only the content, then I would suggest a SingleChildScrollView with a Row (note: Make sure to set the scrollDirection: Axis.horizontal)
import 'package:flutter/material.dart';
final Color darkBlue = Color.fromARGB(255, 18, 32, 47);
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
theme: ThemeData.dark().copyWith(scaffoldBackgroundColor: darkBlue),
debugShowCheckedModeBanner: false,
home: Scaffold(
body: SafeArea(
child: Container(
// height: 100, // no need to specify here
color: Colors.white,
child: SingleChildScrollView(
scrollDirection: Axis.horizontal,
child: Row(
children: <Widget>[
Container(
height: 300,
width: 300,
color: Colors.amber[600],
child: const Center(child: Text('Entry A')),
),
Container(
height: 100,
color: Colors.amber[500],
child: const Center(child: Text('Entry B')),
),
Container(
height: 50,
width: 100,
color: Colors.amber[100],
child: const Center(child: Text('Entry C')),
),
Container(
height: 300,
width: 300,
color: Colors.amber[600],
child: const Center(child: Text('Entry A')),
),
Container(
height: 100,
color: Colors.amber[500],
child: const Center(child: Text('Entry B')),
),
Container(
height: 50,
width: 100,
color: Colors.amber[100],
child: const Center(child: Text('Entry C')),
),
Container(
height: 300,
width: 300,
color: Colors.amber[600],
child: const Center(child: Text('Entry A')),
),
Container(
height: 100,
color: Colors.amber[500],
child: const Center(child: Text('Entry B')),
),
Container(
height: 50,
width: 100,
color: Colors.amber[100],
child: const Center(child: Text('Entry C')),
),
Container(
height: 300,
width: 300,
color: Colors.amber[600],
child: const Center(child: Text('Entry A')),
),
Container(
height: 100,
color: Colors.amber[500],
child: const Center(child: Text('Entry B')),
),
Container(
height: 50,
width: 100,
color: Colors.amber[100],
child: const Center(child: Text('Entry C')),
),
Container(
height: 300,
width: 300,
color: Colors.amber[600],
child: const Center(child: Text('Entry A')),
),
Container(
height: 100,
color: Colors.amber[500],
child: const Center(child: Text('Entry B')),
),
Container(
height: 50,
width: 100,
color: Colors.amber[100],
child: const Center(child: Text('Entry C')),
),
],
),
)),
),
),
);
}
}
+++++++Added after OP comment+++++++
If you want to use a builder for a dynamic list, you can always define your own too!
import 'dart:math';
import 'package:flutter/material.dart';
final Color darkBlue = Color.fromARGB(255, 18, 32, 47);
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
var _randHeight = Random();
List<int> someList = [
1,
2,
3,
4,
5,
7,
8,
9,
10,
11,
12,
13,
14,
15,
16,
17,
18,
19,
20
];
var randHeight = Random();
@override
Widget build(BuildContext context) {
return MaterialApp(
theme: ThemeData.dark().copyWith(scaffoldBackgroundColor: darkBlue),
debugShowCheckedModeBanner: false,
home: Scaffold(
body: SafeArea(
child: Container(
color: Colors.white,
child: SingleChildScrollView(
scrollDirection: Axis.horizontal,
child: Row(
crossAxisAlignment: CrossAxisAlignment.center,
children: _createChildren(),
),
)),
),
),
);
}
List<Widget> _createChildren() {
return List<Widget>.generate(someList.length, (int index) {
return Container(
color: Colors.red,
width: 100,
height: _randHeight.nextInt(300).toDouble(),
child: Text(someList[index].toString(),
style: TextStyle(color: Colors.black)),
);
});
}
}
![Sasank Sunkavalli](https://i.stack.imgur.com/Jxaga.jpg?s=256&g=1)
Comments
-
Sasank Sunkavalli over 1 year
I am using
ListView.builder
(scrollDirection: Horizontal) widget inside aContainer
in Flutter. The main Axis of the ListView is taking up the entire screen width which is expected. I want the ListView's crossAxis(vertical direction) to take up the ListView's Item height (only wrapping the content), but it is taking up the entire screen height.I have created the DartPard to explain the Issue. I want the ListView to take up the Item height and not the entire screen height. Dart Pad Link : DartPard which shows the issue I am facing
import 'package:flutter/material.dart'; final Color darkBlue = Color.fromARGB(255, 18, 32, 47); void main() { runApp(MyApp()); } class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return MaterialApp( theme: ThemeData.dark().copyWith(scaffoldBackgroundColor: darkBlue), debugShowCheckedModeBanner: false, home: Scaffold( body: SafeArea( child: Container( color: Colors.white, child: ListView.builder( itemCount: 10, scrollDirection: Axis.horizontal, itemBuilder: (context, index) { return Container( color: Colors.red, child: Text( 'Item $index', style: TextStyle(color: Colors.black), ), ); }, ), ), ), ), ); } }
Few workarounds which will work :
- Using
Row
orWrap
instead ofListView
. - Giving a Fixed height to the ListView.
I know the above listed approaches will work. But I want to achieve this using a ListView only.
- Using
-
Sasank Sunkavalli over 3 yearsshrinkWrap will shrink the ListView along the main axis. I have asked for the Cross Axis.
-
Sasank Sunkavalli over 3 yearsthere is no way other than using a fixed height for the ListView ?
-
Gene over 3 yearsNo, I believe ListViews require the same CrossAxis size for each object. I updated the answer with what I believe you are looking for
-
Sasank Sunkavalli over 3 yearsYes Using a Row will solve my Issue. But I need to use a ListView.builder() since the list is dynamic and I even want to paginate the list(Items more than 1000 items)
-
Gene over 3 yearsPerhaps you can define your own builder? Check updated answer