Flutter: Auto Vertical Height in ListView.builder
Asked Answered
R

7

23

I'm trying to show some Cards with the ListView.builder
I want to set the heights of each card automatically to the height of its children content

class HomePage extends StatelessWidget {
 Widget _buildListItems(BuildContext context, DocumentSnapshot document) {
  return Center(
   child: Card(
    child: Column(
      children: <Widget>[
        ListTile(
          title: Text(document['title']),
          subtitle: Text(document['subtitle']),
        ),
        Expanded(
          child: Container(
            padding: EdgeInsets.all(20.0),
            child: Text(
              document['summary'],
              softWrap: true,
            ),
          ),
        )
      ],
    ),
  ),
);
}


@override
Widget build(BuildContext context) {
return Scaffold(
  appBar: AppBar(
    title: Text('Title'),
    centerTitle: true,
  ),
  body: StreamBuilder(
    stream: Firestore.instance.collection('randomDB').snapshots(),
    builder: (context, snapshot) {
      if (!snapshot.hasData) return const Text('Loading...');
      return ListView.builder(
        itemExtent: 225.0,
        itemCount: snapshot.data.documents.length,
        itemBuilder: (context, index) =>
            _buildListItems(context, snapshot.data.documents[index]),
      );
    },
  ),
}

When document['summary'] is too long, it makes the text overflow through the card widget. For this time all I do is increase itemExtent in ListView.Builder

Is there a way to set the heights of ListView dynamically?

Reviel answered 3/1, 2019 at 6:45 Comment(0)
B
48

Just add shrinkWrap: true.

& Remove itemExtent: 225.0,

ListView.builder(
  shrinkWrap: true,
  itemCount:  snapshot.data.documents.length,
  itemBuilder: (context, index) =>
        _buildListItems(context, snapshot.data.documents[index]),
 },
),
Bentley answered 27/10, 2020 at 4:55 Comment(3)
this works great and is probably the easiest most flexible solution to setting using ListView.builder in a Column. ThanksVashti
One of the best and working solution, saves a lots of time and "Space"! thanks.Company
This is awesome my friendEffluence
S
12

I believe the column has something called the mainAxisSize property

Column(
  mainAxisSize: MainAxisSize.min,
)

MainAxisSize.min will make the Column size stretch to the minimum size of the children. Opposite to it is MainAxisSize.max that will stretch to the maximum size that it can achieve.

But I haven't tested it yet tho. Hope it will help

Socket answered 3/1, 2019 at 7:21 Comment(0)
K
2

you can use my implementation

Widget adapter(List<String> strings){
    List<Widget> widgets= List<Widget>();
    for(int i=0;i<strings.length;i++){
      widgets.add(Text(strings[i]));
    }

    Row row=Row(
            children: <Widget>[
              Column(
                mainAxisSize: MainAxisSize.min,
                crossAxisAlignment: CrossAxisAlignment.start,
                children:widgets
              ),
            ],
          );
    return row;
  }

This example displays a list of strings

Knowles answered 2/6, 2019 at 21:48 Comment(0)
T
1
 ListView.builder(
                        padding: EdgeInsets.zero,
                        shrinkWrap: true,
                        itemCount: provider.products.length,
                        itemBuilder: (BuildContext context, int index) {
                          return InkWell(
                            onTap: () => viewProductDetail(provider.products[index]),
                            child: const OrderDetailsWidgets().orderedProducts(
                              title: provider.products[index].itemName ?? '',
                              price: '---',
                              img: provider.products[index].productImage ??
                                  'request-list-image.png',
                              context: context,
                            ),
                          );
                        },
                      ),

adding zero padding for listview.builder reduced the height

Tetrabranchiate answered 26/1, 2023 at 13:47 Comment(0)
P
0

Just don't specify the itemExtent parameter.

Or just give it a null value, instead of 225.0

This way, the child will get its exact needed height into the ListView

Prototrophic answered 12/7, 2019 at 15:41 Comment(0)
H
0

Try

class HomePage extends StatelessWidget {
 Widget _buildListItems(BuildContext context, DocumentSnapshot document) {
  return Center(
   child: Card(
    child: Column(
      mainAxisSize: MainAxisSize.min,
      children: <Widget>[
        Flexible(
          ListTile(
          title: Text(document['title']),
          subtitle: Text(document['subtitle']),
        ),
        ),
        Expanded(
          child: Container(
            padding: EdgeInsets.all(20.0),
            child: Text(
              document['summary'],
              softWrap: true,
            ),
          ),
        )
      ],
    ),
  ),
);
}
Hieratic answered 26/1, 2022 at 16:4 Comment(1)
As it’s currently written, your answer is unclear. Please edit to add additional details that will help others understand how this addresses the question asked. You can find more information on how to write good answers in the help center.Sycophancy
D
0

Just set shrinkWrap: true, the listview will automatically take the required height.

Dune answered 4/9, 2023 at 5:32 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.