Flutter - determines the scroll position of a ListView, top or bottom?

I am trying to implement an infinite scroll function .

I tried using ListViewinside NotificationListenerto detect scroll events, but I don't see an event that says the scroll has reached the bottom of the view.

What would be the best way to achieve this?

+15
source share
5 answers

You can use ListView.builderto create a scroll list with unlimited elements. Your itemBuilderwill be called as needed when new cells are detected.

, , controller addListener ScrollController. position ScrollController , .

+22
_scrollController = new ScrollController();

    _scrollController.addListener(
        () {
            double maxScroll = _scrollController.position.maxScrollExtent;
            double currentScroll = _scrollController.position.pixels;
            double delta = 200.0; // or something else..
            if ( maxScroll - currentScroll <= delta) { // whatever you determine here
                //.. load more
            }
        }
    );

....

+6
// create an instance variable
var _controller = ScrollController(); 

@override
void initState() {
  super.initState();

  // set up listener here
  _controller.addListener(() {
    if (_controller.position.atEdge) {
      if (_controller.position.pixels == 0)
        // you are at top position
      else
        // you are at bottom position
    }
  });
}

:

ListView(controller: _controller) // assign it like this
+5

. ChangeNotifie r . , API.

class DashboardAPINotifier extends ChangeNotifier {
   bool _isLoading = false;
    get getIsLoading => _isLoading;
    set setLoading(bool isLoading) => _isLoading = isLoading;
}

DashboardAPINotifier.

@override
  void initState() {
    super.initState();
    _dashboardAPINotifier = DashboardAPINotifier();
    _hitDashboardAPI(); // init state

    _dashboardAPINotifier.addListener(() {
      if (_dashboardAPINotifier.getIsLoading) {
        print("loading is true");
        widget._page++; // For API page
        _hitDashboardAPI(); //Hit API
      } else {
        print("loading is false");
      }
    });

  }

- API. SliverList, API.

SliverList(delegate: new SliverChildBuilderDelegate(
       (BuildContext context, int index) {
        Widget listTile = Container();
         if (index == widget._propertyList.length - 1 &&
             widget._propertyList.length <widget._totalItemCount) {
             listTile = _reachedEnd();
            } else {
                    listTile = getItem(widget._propertyList[index]);
                   }
            return listTile;
        },
          childCount: (widget._propertyList != null)? widget._propertyList.length: 0,
    addRepaintBoundaries: true,
    addAutomaticKeepAlives: true,
 ),
)


_reachEnd() method take care to hit the api. It trigger the '_dashboardAPINotifier._loading'

// Function that initiates a refresh and returns a CircularProgressIndicator - Call when list reaches its end
  Widget _reachedEnd() {
    if (widget._propertyList.length < widget._totalItemCount) {
      _dashboardAPINotifier.setLoading = true;
      _dashboardAPINotifier.notifyListeners();
      return const Padding(
        padding: const EdgeInsets.all(20.0),
        child: const Center(
          child: const CircularProgressIndicator(),
        ),
      );
    } else {
      _dashboardAPINotifier.setLoading = false;
      _dashboardAPINotifier.notifyListeners();
      print("No more data found");
      Utils.getInstance().showSnackBar(_globalKey, "No more data found");
    }
  }

Note. After the API response, you must notify the listener,

setState(() {
        _dashboardAPINotifier.setLoading = false;
        _dashboardAPINotifier.notifyListeners();
        }
+2
source

I would like to add an example for the answer provided by Colleen Jackson . See the following snippet

    var _scrollController = ScrollController();
    _scrollController.addListener(() {
      if (_scrollController.position.pixels == _scrollController.position.maxScrollExtent) {
        // Perform your task
      }
    });

This will only work when the last item is visible in the list.

0
source

Source: https://habr.com/ru/post/1686263/


All Articles