xuelongqy / flutter_easy_refresh

A flutter widget that provides pull-down refresh and pull-up load.
https://xuelongqy.github.io/flutter_easy_refresh/
MIT License
3.83k stars 628 forks source link

当EasyRefresh里面存在其他含ScrollController的widget时,其他Controller调用animateTo会导致EasyRefresh的IndicatorMode状态重置 #843

Open gdmec07120836 opened 2 days ago

gdmec07120836 commented 2 days ago

先看效果 https://github.com/xuelongqy/flutter_easy_refresh/assets/6902443/edccc6c3-fa6e-48dd-b3ff-337b50a5bcdf

可以看到黄色的tab切换之后下拉刷新CupertinoHeader消失了,调试发现是_offset:0.0,IndicatorMode的状态变成了IndicatorMode.inactive log 再进一步调试发现是Swiper开了自动切换,里面的TransformerPageController调用了animateTo,导致EasyRefresh的ScrollPhysics也被回调了,重新检测了滑动边界。 关键代码: Swiper切换Ui的时候这里的短点也会执行 easy代码

大佬可以去试一下。 easy_refresh: 3.4.0 card_swiper: 3.0.1 用其他Controller应该也是这个效果,我懒得重新写就直接用这个widget了

gdmec07120836 commented 2 days ago

测试代码忘了贴:

import 'dart:async';
import 'package:flutter/material.dart';
import 'package:easy_refresh/easy_refresh.dart';
import 'package:card_swiper/card_swiper.dart';

class TestData{
  String name;
  TestData({required this.name});
}

class EasyRefreshTest extends StatefulWidget {
  const EasyRefreshTest({super.key});

  @override
  State<EasyRefreshTest> createState() => _EasyRefreshTestState();
}

class _EasyRefreshTestState extends State<EasyRefreshTest> {
  EasyRefreshController _refreshController = EasyRefreshController();
  List<TestData> list = [];

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("EasyRefresh"),
      ),
      body: EasyRefresh(
        controller: _refreshController,
        refreshOnStart: true,
        header: CupertinoHeader(
            position: IndicatorPosition.locator,
            userWaterDrop: false,
            triggerOffset: 10
        ),
        footer: CupertinoFooter(position: IndicatorPosition.locator),
        onRefresh: (){
          requestData();
        },
        onLoad: (){
          requestData();
        },
        child: CustomScrollView(
          // controller: widget.viewModel.scrollController,
          slivers: [
            HeaderLocator.sliver(
              clearExtent: false,
            ),
            SliverList(
                delegate: SliverChildBuilderDelegate(
                      (BuildContext context, int index) {
                        if(index == 0){
                          return getSwiper();
                        }
                    return Container(
                      width: 100,
                      height: 60,
                      alignment: Alignment.center,
                      color: Colors.green,
                      child: Text("list-item-$index"),
                    );
                  },
                  childCount: list.length,
                )),
            FooterLocator.sliver(
              clearExtent: false,
            ),
          ],
        ),
      ),
    );
  }
  @override
  void dispose() {
    _refreshController.dispose();
    super.dispose();
  }

  void requestData() async {
    await simulateDelay(Duration(seconds: 2));
    setState(() {

    });
  }

  Future<List<TestData>> simulateDelay(Duration duration) {
    final completer = Completer<List<TestData>>();

    Timer(duration, () {
      list.clear();
      for(int i = 0;i<20;i++){
        list.add(TestData(name: "测试一下i=$i"));
      }
      completer.complete(list); // 完成 Future
    });

    return completer.future;
  }

  Widget getSwiper(){
    return Container(
      width: 100,
      height: 100,
      child: RepaintBoundary(
        child: Swiper(
          index: 0,
          itemCount: 3,
          autoplay: true,
          key: UniqueKey(),
          loop: true,
          scrollDirection: Axis.horizontal,
          autoplayDisableOnInteraction: true,
          scale: 1,
          viewportFraction: 1.0,
          itemBuilder: (BuildContext context, int index) {
            return Container(
              width: 100,
              height: 100,
              alignment: Alignment.center,
              color: Colors.yellow,
              child: Text("item-$index"),
            );
          },
        ),
      ),
    );
  }
}