robert-luoqing / flutter_list_view

MIT License
47 stars 17 forks source link

bug in ensureVisible; added page-up page-down functions #28

Closed graemep-nz closed 8 months ago

graemep-nz commented 8 months ago

I need the capability to do page-up and page-down in the listview where page-down scrolls the listview down by a little bit less than the height of the viewport - or alternatively, jumps to one more than the last fully visible index in the view and always jumps by at least one index. something like this

  int getLastFullyVisibleIndex() {
    // paintedElements
    int last = 0;
    var flutterListViewRender = renderObject as FlutterListViewRender;
    var viewportHeight = flutterListViewRender.currentViewportHeight ?? 0;
    for (var item in flutterListViewRender.paintedElements) {
      if (item.index > last   &&
          item.offset > 0 &&
          item.offset + item.height < viewportHeight) {
      {
        last = item.index;
      }
    }
    return last;
  }

  void pageDown() {
    int fred = getLastFullyVisibleIndex();
    jumpToIndex(fred + 1);
  }
graemep-nz commented 8 months ago

This code in flutter_list_view_element.dart is wrong - this expression item.offset + item.height < viewportHeight doesn't work because item.offset is the offset from the first element in the list, not the offset from the start of the viewport

  void ensureVisible(int index, double offset, bool basedOnBottom) {
    assert(index >= 0 && index < childCount,
        "Index should be >=0 and  <= child count");
    // paintedElements
    var flutterListViewRender = renderObject as FlutterListViewRender;
    var viewportHeight = flutterListViewRender.currentViewportHeight ?? 0;
    for (var item in flutterListViewRender.paintedElements) {
      if (item.index == index &&
          item.offset > 0 &&
          item.offset + item.height < viewportHeight) {
        return;
      }
    }

    jumpToIndex(index, offset, basedOnBottom);
  }
graemep-nz commented 8 months ago

I've added some code for pageUp and pageDown plus a fix for ensureVisible. Atttached as zip file.

Also note the assert error message has an error in a few places - it should be as below (less than instead of <=) assert(index >= 0 && index < childCount, "Index should be >=0 and < child count");

  void ensureVisible(int index, double offset, bool? basedOnBottom) {
    assert(index >= 0 && index < childCount,
          "Index should be >=0 and  < child count");
    var sdata = getVisibleIndexData();
    int first = sdata[0];
    int last = sdata[1];
    if (index <= first) {
      jumpToIndex(index, 0, basedOnBottom ?? false);
    } else if (index >= last) {
      jumpToIndex(index, 0, basedOnBottom ?? true);
    }
  }

src.zip