google / flutter.widgets

https://pub.dev/packages/flutter_widgets
BSD 3-Clause "New" or "Revised" License
1.38k stars 486 forks source link

[scrollable_positioned_list] support insert items to top without scroll downwards #311

Open ivk1800 opened 2 years ago

ivk1800 commented 2 years ago

By default, if items are inserted at the "top" of a scrolling container like ListView or CustomScrollView, the top item and all of the items below it are scrolled downwards. In some applications, it's preferable to have the top of the list just grow upwards, without changing the scroll position.

https://api.flutter.dev/flutter/widgets/CustomScrollView-class.html#widgets.CustomScrollView.2

ivk1800 commented 2 years ago

@robert-bitguild may be extends scrollable_positioned_list with keep position? reusing your code?

ivk1800 commented 2 years ago

@robert-bitguild I mean edit PositionedList, replace SliverList by FlutterSliverList and FlutterListViewDelegate.

https://github.com/google/flutter.widgets/blob/a10a102e8b971b132402ac3c42da364b6bc86dba/packages/scrollable_positioned_list/lib/src/positioned_list.dart#L203

I try it, but not work expectably. there are some limitations?

robert-bitguild commented 2 years ago

@ivk1800 https://github.com/google/flutter.widgets/pull/318 may resolve the issue

lxl518000 commented 2 years ago

@ivk1800 #318 may resolve the issueimage looks like commit not work! if it can keep position ,that will be cool!

i tried, but not work. please help to check it . Thanks!

image

finally. it worked! cause i gave the incorrect key!!

Thanks for commit!

robert-bitguild commented 2 years ago

@ivk1800 There are two bugs in my previous PR.

  1. I didn't check widget.onItemKey != null. It broke other behavior.
    if (widget.itemCount > 0 && widget.onItemKey != null) {
      _lastTargetKey = widget.onItemKey!(primary.target);
    } else {
      _lastTargetKey = null;
    }
  2. I remove check the if( primary.target==0) primary.target++. If the condition exist, when you switch keepPositionWithoutScroll in first time, the second item will scroll to first.
    if (widget.keepPositionWithoutScroll) {
      assert(widget.onItemKey != null,
          "Please implement onItemKey if keepPositionWithoutScroll was enabled");
      if (_lastTargetKey != null) {
        var currTargetIndex = _getIndexOfKey();
        if (currTargetIndex != null && currTargetIndex > primary.target) {
          primary.target++;
        }
      }
    }

I have full push the complete PR. include the example code. You can run example directly. https://github.com/google/flutter.widgets/pull/319

Hope it help for you.

Thanks.

kazemashinobu commented 2 years ago

@robert-bitguild If I add more than one item at the same time, it didn't work.

Should we modify

if (widget.keepPositionWithoutScroll) {
      assert(widget.onItemKey != null,
          "Please implement onItemKey if keepPositionWithoutScroll was enabled");
      if (_lastTargetKey != null) {
        var currTargetIndex = _getIndexOfKey();
        if (currTargetIndex != null && currTargetIndex > primary.target) {
          primary.target++;
        }
      }
    }

to

if (widget.keepPositionWithoutScroll) {
      assert(widget.onItemKey != null,
          "Please implement onItemKey if keepPositionWithoutScroll was enabled");
      if (_lastTargetKey != null) {
        var currTargetIndex = _getIndexOfKey();
        if (currTargetIndex != null && currTargetIndex > primary.target) {
          primary.target = currTargetIndex;
        }
      }
    }

Thanks.

robert-bitguild commented 2 years ago

@kazemashinobu great, thanks. I have updated the PR which follows your modified code.