Flutter ListView.builder creates an infinite scroll. How can I set it to stop at the end of content?
Asked Answered
M

3

7

I am using ListView.buildler to layer Widget, into a vertical scroll. My only issue with this approach is that when the scroll reaches the end of my content. It wraps back to the top automatically. Currently I have this:

    new ListView.builder(
    scrollDirection: Axis.vertical,
    key: new Key(randomString(20)),
    reverse: false,
    primary: true,
    itemBuilder: (BuildContext context, int index) {
        return new Column(
        children: <Widget>[
            new Padding(
            padding: _bookPadding,
            child: new Container(
                width: 106.0,
                height: 162.0,
                child: new FadeInImage(
                    placeholder: new AssetImage('assets/loading.gif'),
                    image: this.book.cover)
            ),
            ),
            const Divider(),
            new Padding(
                padding: _bookPadding,
                child: new Text(
                    this.book.bookName,
                    style: getTextStyle())),
            const Divider(),
            new Padding(
            padding: _bookPadding,
            child: new Text(
                'By ' + this.book.author,
                style: getTextStyle(), ),
            ),
           ....

Is it possible to set ListView.builder to no-wrap when it reaches the end?

Monopetalous answered 23/3, 2018 at 0:2 Comment(3)
return null to end ListView.Kilowatthour
Im not sure how to return null in a ListView. Flutter Complains any time a widget or child try's to return null.Monopetalous
Possible duplicate of Dart/Flutter - Flutter - Why ListView is going infiniteMontymonument
M
7

This ended up being pretty easy. Not sure how I missed it from the docs, all I needed to add was an Item count = non-null. In my case, since I am building all of my content in a single Column widget, inside the list-view builder, this is what my builder looks like:

new ListView.builder(
    scrollDirection: Axis.vertical,
    key: new Key(randomString(20)),
    primary: true,
    itemCount: 1,
    itemBuilder: (BuildContext context, int index) {
        return new Column(
        children: <Widget>[ .....

I do wonder about this implementation if its a bad pattern. Will ListView.Builder still render each nested children of Component Column, as each children of Column becomes visible?

From the docs: "Creates a scrollable, linear array of widgets that are created on demand. This constructor is appropriate for list views with a large (or infinite) number of children because the builder is called only for those children that are actually visible."

Monopetalous answered 25/3, 2018 at 17:3 Comment(3)
Why do you put the children in a Column? It makes way more sense to me to put them directly in the itembuilder. The benefit of the itembuilder is that it only builds widgets that are needed, now it builds the Column. The Column will build all its children at once. Also if you have a ListView with only 1 item you probably wanted a SingleChildScrollView. Is there anything of the Column that you need to use?Unessential
@Unessential yes, at first I was working with the Column widget, but found it didnt offer the Scrollable features that I wanted, wrapping it ListView.builder provided the scrolling I wanted. I initially thought that it might extend the loading properties/benefits to widget children. But, as I mentioned above about "questioning" the implementation, it is apparent when setting itemCount=1 that indeed it is loading that entire item. I agree, I will be migrating this implementation to either SIngleChildScrollView or putting them directly in the item builder.Monopetalous
I just answered an example with an easier implementation of the code. You could try that as well.Unessential
U
4

You could skip lots of your code. Sometimes the itemBuilder is very nice, especially when you have lots of widgets and can easily identify your item by index, but you can also use the children directly. An example from the ListView documentation:

new ListView(
  shrinkWrap: true,
  padding: const EdgeInsets.all(20.0),
  children: <Widget>[
    const Text('I\'m dedicating every day to you'),
    const Text('Domestic life was never quite my style'),
    const Text('When you smile, you knock me out, I fall apart'),
    const Text('And I thought I was so smart'),
  ],
)
Unessential answered 26/3, 2018 at 15:45 Comment(0)
P
0

When using ListView.builder one should always remember about specifying itemCount and itemBuilder.

For an intended infinite scroll itemCount might be list.length + 1, in order to show a progress item on the bottom, but otherwise the count should equal to all list items length.

Pictor answered 31/1 at 7:39 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.