skip to Main Content

My problems with ListView.builder in my specific scenario:

  • A height has to be given to ListView.builder so that whatever is inside that can be infinitely scrollable.
  • The shrinkWrap property is only helpful if you are planning to give ListView.builder a predetermined height.

What I require:

A ListView.builder that acts just like a Column which will display all the widgets so that there is no scrolling, so it does not require a height but will be like an Expanded widget.

I want to use ListView.builder as my widgets are generated through Lists and Dictionaries, but if it’s not necessary to use it, please give me an alternative where I can use my Lists and Dictionaries to generate widgets on demand and update the state.

Example:

List<Map> data = [{'data': 'here'}];

// ListView.builder solution:
ListView.builder(
    shrinkWrap: true,
    itemCount: data.length,
    itemBuilder: (context, index) {
        if (condition A) {
            return Text(data[index]['data']);
        } else if (condition B) {
            return Text(data[index]['data']);
        } else {
            return Container();
        }
    }
);
// This solution requires ListView.builder to have its own height
// constraints, so setting a height will cause it to be scrollable if
// the widgets take up space after those constraints are exceeded.
// NeverScrollablePhysics() is not the point here.

// Column solution:
// A widget and for loop is required to build before the build method is called:
List<Widget> widgetList = [];

for (var dataSet in data) {
    // If conditions here:
    widgetList.add(dataSet['data'];
}

return Column(
    children: widgetList,
);
// Problem: Widgets such as FilterChip which use state changes don't
// get updated as these come from a prebuilt Widget variable. Tapping
// on them does nothing.

2

Answers


  1. ListView widget contains a property named "Physics" which can accept "NeverScrollableScrollPhysics()" and that will disable scrolling in your ListView widget. here is an example,

    return Scaffold(
      body: ListView.builder(
        physics: const NeverScrollableScrollPhysics(),
        itemCount: 10,
        itemBuilder: (context, index) => Container(),
      ),
    );
    
    Login or Signup to reply.
  2. I’m not entirely sure if I understood it right, but if-conditions and loops are certainly also possible in Columns. Your example of

    ListView.builder(
        shrinkWrap: true,
        itemCount: data.length,
        itemBuilder: (context, index) {
            if (condition A) {
                return Text(data[index]['data']);
            } else if (condition B) {
                return Text(data[index]['data']);
            } else {
                return Container();
            }
        }
    );
    

    can be rewritten as a Column like

    Column(children: [
      for (final d in data)
        if (condition A)
          Text(d['data'])
        else if (condition B)
          Text(d['data'])
        else
          Container()
    ]);
    

    But I’m not sure if it helps solve your problem.

    EDIT:
    For your follow-up question, maybe this is something that you want?

    Column(children: [
      for (final d in data.map((e) => e['data']))
        if (conditionA)
          Text(d)
        else if (conditionB)
          Text(d)
        else
          Container()
    ]);
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search