robert-luoqing / flutter_list_view

MIT License
45 stars 17 forks source link

设置initIndex超出跳转范围会有一个回弹动画 #30

Closed Marco-Ryus closed 3 months ago

Marco-Ryus commented 4 months ago

假设children共有10个,initIndex设置第8,则列表会在展示时向顶部滑动一段距离再恢复 示例:

class TestHomePage extends StatefulWidget {
  const TestHomePage({Key? key}) : super(key: key);

  @override
  State<TestHomePage> createState() => _TestHomePageState();
}

class _TestHomePageState extends State<TestHomePage> {
  late EasyRefreshController _controller;

  List<List<int>> newTestData = List.generate(8, (index) => [index, index % 2 == 0 ? 50 : 75]);

  FlutterListViewController listViewController = FlutterListViewController();

  StreamController<List<FlutterListViewItemPosition>> streamController = StreamController();

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

    _controller = EasyRefreshController(
      controlFinishRefresh: true,
      controlFinishLoad: true,
    );

    listViewController.sliverController.onPaintItemPositionsCallback =
        (double widgetHeight, List<FlutterListViewItemPosition> positions) {
      var firstIndex = positions.first.index;
      var lastIndex = positions.last.index;

      // if (positions.first.offset + positions.first.height > widgetHeight) {
      //   print('marsru: 第一个偏移量超出屏幕范围,不算做上报');
      // }

      var newList = positions.where((pos) => pos.height + pos.offset < widgetHeight).toList();
      streamController.add(newList);
    };
  }

  @override
  void dispose() {
    _controller.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('EasyRefresh'),
      ),
      body: Column(
        children: [
          Expanded(
            child: EasyRefresh(
              controller: _controller,
              footer: const ClassicFooter(infiniteOffset: null),
              onLoad: () async {
                await Future.delayed(const Duration(seconds: 2));
                if (!mounted) {
                  return;
                }
                int last = newTestData.last[0];
                setState(() {
                  newTestData.addAll([
                    [last + 1, (last + 1) % 2 == 0 ? 50 : 75],
                    [last + 2, (last + 2) % 2 == 0 ? 50 : 75]
                  ]);
                });
                _controller.finishLoad(
                    newTestData.length >= 20 ? IndicatorResult.noMore : IndicatorResult.success);
              },
              child: FlutterListView(
                reverse: true,
                controller: listViewController,
                delegate: FlutterListViewDelegate(
                  (BuildContext context, int index) => _buildCard(newTestData[index]),
                  childCount: newTestData.length,
                  firstItemAlign: FirstItemAlign.end,
                  onItemKey: (index) => newTestData[index][0].toString(),
                  keepPosition: true,
                  initOffsetBasedOnBottom: false,
                  initIndex: 6,
                ),
              ),
            ),
          ),
          Row(
            children: [
              TextButton(
                child: const Text('底部插入新消息'),
                onPressed: () {
                  int first = newTestData.first[0];
                  setState(() {
                    newTestData.insert(0, [first - 1, (first - 1) % 2 == 0 ? 50 : 75]);
                  });
                },
              ),
              TextButton(
                child: const Text('跳转至index为9的消息'),
                onPressed: () {
                  listViewController.sliverController.animateToIndex(
                    9,
                    duration: const Duration(milliseconds: 400),
                    curve: Curves.linear,
                  );
                },
              ),
            ],
          )
        ],
      ),
    );
  }

  Card _buildCard(List<int> newTestData) {
    return Card(
      child: Container(
        alignment: Alignment.center,
        // height: 200,
        height: newTestData[1].toDouble(),
        child: Text('${newTestData[0]}'),
      ),
    );
  }
}

https://github.com/robert-luoqing/flutter_list_view/assets/56830836/146b5d7f-74f0-45ac-9155-d0c9da8ec195

robert-luoqing commented 4 months ago

Fixed, Please update to flutter_list_view: ^1.1.27

Marco-Ryus commented 4 months ago

It works, thx