Flutter - ListView.builder with very large size and does not change

放肆的年华 提交于 2021-02-07 06:16:44

问题


How can I decrease the size of items using the ListView.builder I already tried to tinker with everything in ItemCategory but the size remains the same.

Using the ListView the size is the smallest good according to this images below:

Using the Flutter - Strange ListView behavior after refresh code the items are well-sized, but by changing the ListView toListView.builder the size changes completely and the ItemCategory class is the same

without ListView.builder

with ListView.builder

import 'package:flutter/material.dart';
import 'dart:math';

void main() {
  runApp(new MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return new MaterialApp(
      home: new CategoryPage(),
    );
  }
}

class CategoryPage extends StatefulWidget {
  @override
  CategoryPageState createState() => new CategoryPageState();
}

class CategoryPageState extends State<CategoryPage> {
  Color blueAppBar = new Color(0xFF26C6DA);
  List<Widget> listCategories = [];
  List listaDB = [];
  List lista2DB = [];
  List listaCategory;
  final List<Widget> children = <Widget>[];

  String randomString(int length) {
    var rand = new Random();
    var codeUnits = new List.generate(
        length, 
        (index){
          return rand.nextInt(33)+89;
        }
    );   
    return new String.fromCharCodes(codeUnits);
  }

  @override
  void initState() {
    this.listaDB = 
      [
        [{'category': 'foo01'}],
        [{'category': 'foo02'}],
        [{'category': 'foo03'}],
        [{'category': 'foo04'}],
        [{'category': 'foo05'}],
        [{'category': 'foo06'}],
        [{'category': 'foo07'}],
        [{'category': 'foo08'}],
        [{'category': 'foo09'}],
        [{'category': 'foo10'}],
        [{'category': 'foo11'}],
        [{'category': 'foo12'}],
        [{'category': 'foo13'}],
        [{'category': 'foo14'}],
        [{'category': 'foo15'}],
        [{'category': 'foo16'}],
        [{'category': 'foo17'}],
        [{'category': 'foo18'}],
        [{'category': 'foo19'}],
        [{'category': 'foo20'}],
        [{'category': 'foo21'}],
        [{'category': 'foo22'}],
        [{'category': 'foo23'}],
        [{'category': 'foo24'}]
      ];

    for(var i in this.listaDB) {
      var category = i[0]['category'];
      children.add(
        new ItemCategory(
          key: new Key(randomString(20)),
          category: category,
        )
      );
    }
  }

  @override
  Widget build(BuildContext context) {   
    return new Scaffold( 
      appBar: new AppBar(
        title: new Text('Categories'),
        backgroundColor: blueAppBar,
        actions: <Widget>[
          new IconButton(
            icon: new Icon(Icons.refresh),
            onPressed: () {
              setState(() {
                children.clear();
                for(var i in this.lista2DB) {
                  var category = i[0]['category'];
                  children.add(
                    new ItemCategory(
                      key: new Key(randomString(20)),
                      category: category,
                    )
                  );
                }
              });
            },
          )
        ],
      ),
      body: new ListView.builder(
        itemBuilder: (BuildContext context, int index) => children[index],
        itemExtent: 128.0,
        itemCount: children.length,
      ),
    );
  }
}

class ItemCategory extends StatelessWidget {
  final String category;

  ItemCategory({
    Key key,
    this.category}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return new Container(
      decoration: new BoxDecoration(
        border: new Border(
          top: new BorderSide(style: BorderStyle.solid, color: Colors.black26),
        ),
        color: new Color(0xFFFAFAFA),
      ),
      margin: new EdgeInsets.only(top: 0.0, bottom: 0.0),
      child: new Row(
        mainAxisAlignment: MainAxisAlignment.start,
        crossAxisAlignment: CrossAxisAlignment.center,
        children: <Widget>[
          new Expanded(
            child: new Row(
              mainAxisAlignment: MainAxisAlignment.spaceBetween,
              children: <Widget>[
                new Container(
                  margin: new EdgeInsets.only(left: 16.0),
                  padding: new EdgeInsets.only(right: 40.0, top: 4.5, bottom: 4.5),
                  child: new Row(
                    children: <Widget>[
                      new Container(
                        margin: new EdgeInsets.only(right: 16.0),
                        child: new Icon(
                          Icons.brightness_1,
                          color: Colors.black,
                          size: 35.0,
                        ),
                      ),
                      new Text(this.category),
                    ],
                  )
                )
              ],
            ),
          )
        ],
      ),
    );
  }
}

回答1:


To work with the correct size simply change the value itemExtent: 128.0 to a smaller number such asitemExtent: 46.0

That defines the size of each child, you can remove it and the builder will calculate the size for each item based on its dimensions. Removing itemExtent to be automatically calculate.

The ListView also needs a key, because when updating to another list, if each list does not have its own key the list is mounted in the wrong way.

The ListView code should look like this:

body: new ListView.builder(
  key: new Key(randomString(20)), //new
  itemBuilder: (BuildContext context, int index) => children[index],
  //itemExtent: 128.0,
  itemCount: children.length,
),

By making this change the list is mounted correctly.




回答2:


Its good practice when we use itemExtent because

Specifying an [itemExtent] is more efficient than letting the children determine their own extent because the scrolling machinery can make use of the foreknowledge of the children's extent to save work, for example, when the scroll position changes drastically.

So, when we declare any value for itemExtent it will help Listview to render fastly, as now calculation of height among widget is not the concern. Hence static height works in this case.



来源:https://stackoverflow.com/questions/48673795/flutter-listview-builder-with-very-large-size-and-does-not-change

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!