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.88k stars 633 forks source link

NestedScrollView + TabBarView + EasyRefresh 的时候,调用 EasyRefreshController.callRefresh()无反应 #676

Closed lan2000 closed 1 year ago

lan2000 commented 1 year ago

easy_refresh: ^3.3.0+1

下面代码,点击TextButton按钮,触发调用 EasyRefreshController.callRefresh()无反应,不能触发刷新的动作。

环境: Flutter (Channel stable, 3.3.9, on Microsoft Windows [版本 10.0.19042.630], locale zh-CN) • Flutter version 3.3.9 on channel stable at D:\flutter\flutter • Upstream repository https://github.com/flutter/flutter/ • FLUTTER_GIT_URL = https://github.com/flutter/flutter/ • Framework revision b8f7f1f986 (3 months ago), 2022-11-23 06:43:51 +0900 • Engine revision 8f2221fbef • Dart version 2.18.5 • DevTools version 2.15.0 Connected device (4 available) • WLZ AL10 (mobile) • 10.168.3.210:5555 • android-arm64 • Android 10 (API 29)

代码:


import 'dart:async';

import 'package:example/widget/skeleton_item.dart';
import 'package:flutter/material.dart';
import 'package:easy_refresh/easy_refresh.dart';

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

  @override
  NestedScrollViewPageState createState() {
    return NestedScrollViewPageState();
  }
}

class NestedScrollViewPageState extends State<NestedScrollViewPage>
    with SingleTickerProviderStateMixin {
  late TabController _tabController;

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

  @override
  void initState() {
    super.initState();
    _tabController = TabController(length: 2, vsync: this);
  }

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

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      // appBar: AppBar(
      //   title: Text('AppBar'),
      // ),
        body: NestedScrollView(
          // controller: sc,
          headerSliverBuilder: (BuildContext context, bool innerBoxIsScrolled) {
            var widgets = <Widget>[
              SliverAppBar(
                title: Text('SliverAppBar'),
                expandedHeight: 200.0,
                pinned: true,
                floating: false,
                flexibleSpace: FlexibleSpaceBar(
                  //centerTitle: true,
                    collapseMode: CollapseMode.pin,
                    background: Container(
                      color: Colors.red,
                    )),
                bottom: TabBar(
                  controller: _tabController,
                  labelColor: Colors.black87,
                  isScrollable: false,
                  unselectedLabelColor: Colors.grey,
                  tabs: [
                    Tab( text: "PAGE1"),
                    Tab( text: "PAGE2"),
                  ],
                ),
              ),

            ];
            return widgets;
          },
          body: TabBarView(
            controller: _tabController,
            children: <Widget>[
              TestAPage(),
              TestAPage(),
            ],
          ),
        ));
  }
}

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

  @override
  State<TestAPage> createState() => _TestAPageState();
}

class _TestAPageState extends State<TestAPage>
    with AutomaticKeepAliveClientMixin {
  EasyRefreshController controller1 = EasyRefreshController(
    controlFinishRefresh: true,
    controlFinishLoad: true,
  );
  int _listCount = 110;

  @override
  Widget build(BuildContext context) {
    super.build(context);
    return Scaffold(
      body: EasyRefresh(
        controller: controller1,
        header: const MaterialHeader(
          position: IndicatorPosition.locator,
        ),
        footer: const ClassicFooter(
          // clamping: true,
          // infiniteOffset: null,
          position: IndicatorPosition.locator,
          dragText: 'Pull to load',
          armedText: 'Release ready',
          readyText: 'Loading...',
          processingText: 'Loading...',
          processedText: 'Succeeded',
          noMoreText: 'No more',
          failedText: 'Failed',
          messageText: 'Last updated at %T',
        ),
        child: CustomScrollView(
          slivers: [
            const HeaderLocator.sliver(),
            SliverToBoxAdapter(
              child: TextButton(
                onPressed: () async {
                  print('----callRefresh');
                  controller1.callRefresh(force: true);
                },
                child: Text('callRefresh'),
              ),
            ),
            SliverList(
              delegate: SliverChildBuilderDelegate((context, index) {
                return SkeletonItem(
                  index: index,
                );
              }, childCount: _listCount),
            ),
            const FooterLocator.sliver(),
          ],
        ),
        onRefresh: () async {
          await Future.delayed(const Duration(seconds: 2), () async {
            if (mounted) {
              setState(() {
                _listCount = 1;
              });
              controller1.finishRefresh(IndicatorResult.success);
              controller1.resetFooter();
            }
          });
        },
        onLoad: () async {
          await Future.delayed(const Duration(seconds: 1), () {
            if (mounted) {
              setState(() {
                // _listCount = 0;
                _listCount += 1;
              });
              controller1.finishLoad(IndicatorResult.success);
            }
          });
        },
      ),
    );
  }

  @override
  bool get wantKeepAlive => true;
}
lan2000 commented 1 year ago

看到解决方法了 https://github.com/xuelongqy/flutter_easy_refresh/issues/616