flutter中SmartRefresher的错误(不要使用一个refreshController到多个SmartRefresher,这会导致一些意想不到的bug)

问题描述 投票:0回答:8

在控制器中:

 RefreshController refreshController = RefreshController(initialRefresh: false);

  @override
  void onInit() {
    fetchServices();
    fetchCategory();
    super.onInit();
  }



  Future<bool> fetchServices({bool isRefresh = false}) async {

    if (isRefresh) {
      currentPage = 1;
    } else {
      if (currentPage > totalPages) {
        refreshController.loadNoData();
        return false;
      }
    }

    try {
      isLoading(true);
      var servicesData =  await ServicesDb.fetchServices(currentPage);
      var services = servicesData.data;

      if (services != null) {

        if(isRefresh) {
          servicesList.value = services;
        } else {
          servicesList.value.addAll(services);
        }
        currentPage++;
        totalPages = servicesData.meta.lastPage;
        return true;
      } else {
        return false;
      }
    } finally {
      isLoading(false);
    }
  }

在视图中:

Widget build(BuildContext context) {
    return Obx(() {
    if(controller.isLoading.value == true || controller.isLoadingSearch.value == true) {
      return const Center(child: CircularProgressIndicator(color: Colors.black,));
    } else {
      return SizedBox(
        height: MediaQuery.of(context).size.height,
        child: SmartRefresher(
          controller: controller.refreshController ,
          enablePullUp: true,
          onRefresh: ()=> controller.onRefresh(),
          onLoading: () => controller.onLoading(),
          child: StaggeredGridView.countBuilder(
            crossAxisCount: 2,
            itemCount: controller.servicesList.length,
            crossAxisSpacing: 16,
            mainAxisSpacing: 16,
            itemBuilder: (context, index) {

我收到此错误:当进行热重载或将方向从纵向更改为横向时,反之亦然。当再次进行热重载时,错误消失>>

======== Exception caught by widgets library =======================================================
The following assertion was thrown building Obx(has builder, state: _ObxState#8fd5c):
Don't use one refreshController to multiple SmartRefresher,It will cause some unexpected bugs mostly in TabBarView
'package:pull_to_refresh/src/smart_refresher.dart':
Failed assertion: line 608 pos 12: '_refresherState == null'

The relevant error-causing widget was: 
  Obx Obx:file:///F:/myServices/my_services/lib/ui/widgets/services_widget.dart:13:12
When the exception was thrown, this was the stack: 
#2      RefreshController._bindState (package:pull_to_refresh/src/smart_refresher.dart:608:12)
#3      SmartRefresherState.initState (package:pull_to_refresh/src/smart_refresher.dart:519:23)
#4      StatefulElement._firstBuild (package:flutter/src/widgets/framework.dart:4805:57)
#5      ComponentElement.mount (package:flutter/src/widgets/framework.dart:4638:5)
...     Normal element mounting (50 frames)
#55     Element.inflateWidget (package:flutter/src/widgets/framework.dart:3673:14)
#56     Element.updateChild (package:flutter/src/widgets/framework.dart:3425:18)
#57     SliverMultiBoxAdaptorElement.updateChild (package:flutter/src/widgets/sliver.dart:1242:37)
#58     SliverMultiBoxAdaptorElement.createChild.<anonymous closure> (package:flutter/src/widgets/sliver.dart:1227:20)
#59     BuildOwner.buildScope (package:flutter/src/widgets/framework.dart:2573:19)
#60     SliverMultiBoxAdaptorElement.createChild (package:flutter/src/widgets/sliver.dart:1220:12)
#61     RenderSliverMultiBoxAdaptor._createOrObtainChild.<anonymous closure> (package:flutter/src/rendering/sliver_multi_box_adaptor.dart:349:23)
#62     RenderObject.invokeLayoutCallback.<anonymous closure> (package:flutter/src/rendering/object.dart:1968:59)
#63     PipelineOwner._enableMutationsToDirtySubtrees (package:flutter/src/rendering/object.dart:916:15)
#64     RenderObject.invokeLayoutCallback (package:flutter/src/rendering/object.dart:1968:14)
#65     RenderSliverMultiBoxAdaptor._createOrObtainChild (package:flutter/src/rendering/sliver_multi_box_adaptor.dart:338:5)
#66     RenderSliverMultiBoxAdaptor.insertAndLayoutChild (package:flutter/src/rendering/sliver_multi_box_adaptor.dart:484:5)
#67     RenderSliverList.performLayout.advance (package:flutter/src/rendering/sliver_list.dart:239:19)
#68     RenderSliverList.performLayout (package:flutter/src/rendering/sliver_list.dart:282:12)
#69     RenderObject.layout (package:flutter/src/rendering/object.dart:1858:7)
#70     RenderSliverEdgeInsetsPadding.performLayout (package:flutter/src/rendering/sliver_padding.dart:137:12)
#71     RenderSliverPadding.performLayout (package:flutter/src/rendering/sliver_padding.dart:371:11)
#72     RenderObject.layout (package:flutter/src/rendering/object.dart:1858:7)
#73     RenderViewportBase.layoutChildSequence (package:flutter/src/rendering/viewport.dart:510:13)
#74     RenderShrinkWrappingViewport._attemptLayout (package:flutter/src/rendering/viewport.dart:1923:12)
#75     RenderShrinkWrappingViewport.performLayout (package:flutter/src/rendering/viewport.dart:1881:20)
#76     RenderObject.layout (package:flutter/src/rendering/object.dart:1858:7)
#77     RenderProxyBoxMixin.performLayout (package:flutter/src/rendering/proxy_box.dart:116:14)
#78     RenderObject.layout (package:flutter/src/rendering/object.dart:1858:7)
#79     RenderProxyBoxMixin.performLayout (package:flutter/src/rendering/proxy_box.dart:116:14)
#80     RenderObject.layout (package:flutter/src/rendering/object.dart:1858:7)
#81     RenderProxyBoxMixin.performLayout (package:flutter/src/rendering/proxy_box.dart:116:14)
#82     RenderObject.layout (package:flutter/src/rendering/object.dart:1858:7)
#83     RenderProxyBoxMixin.performLayout (package:flutter/src/rendering/proxy_box.dart:116:14)
#84     RenderObject.layout (package:flutter/src/rendering/object.dart:1858:7)
#85     RenderProxyBoxMixin.performLayout (package:flutter/src/rendering/proxy_box.dart:116:14)
#86     RenderObject.layout (package:flutter/src/rendering/object.dart:1858:7)
#87     RenderProxyBoxMixin.performLayout (package:flutter/src/rendering/proxy_box.dart:116:14)
#88     RenderObject.layout (package:flutter/src/rendering/object.dart:1858:7)
#89     RenderProxyBoxMixin.performLayout (package:flutter/src/rendering/proxy_box.dart:116:14)
#90     RenderObject.layout (package:flutter/src/rendering/object.dart:1858:7)
#91     RenderProxyBoxMixin.performLayout (package:flutter/src/rendering/proxy_box.dart:116:14)
#92     RenderCustomPaint.performLayout (package:flutter/src/rendering/custom_paint.dart:545:11)
#93     RenderObject.layout (package:flutter/src/rendering/object.dart:1858:7)
#94     RenderProxyBoxMixin.performLayout (package:flutter/src/rendering/proxy_box.dart:116:14)
#95     RenderObject.layout (package:flutter/src/rendering/object.dart:1858:7)
#96     MultiChildLayoutDelegate.layoutChild (package:flutter/src/rendering/custom_layout.dart:171:12)
#97     _ScaffoldLayout.performLayout (package:flutter/src/material/scaffold.dart:1097:7)
#98     MultiChildLayoutDelegate._callPerformLayout (package:flutter/src/rendering/custom_layout.dart:240:7)
#99     RenderCustomMultiChildLayoutBox.performLayout (package:flutter/src/rendering/custom_layout.dart:404:14)
#100    RenderObject.layout (package:flutter/src/rendering/object.dart:1858:7)
#101    RenderProxyBoxMixin.performLayout (package:flutter/src/rendering/proxy_box.dart:116:14)
#102    RenderObject.layout (package:flutter/src/rendering/object.dart:1858:7)
#103    RenderProxyBoxMixin.performLayout (package:flutter/src/rendering/proxy_box.dart:116:14)
#104    _RenderCustomClip.performLayout (package:flutter/src/rendering/proxy_box.dart:1388:11)
#105    RenderObject.layout (package:flutter/src/rendering/object.dart:1858:7)
#106    RenderProxyBoxMixin.performLayout (package:flutter/src/rendering/proxy_box.dart:116:14)
#107    RenderObject.layout (package:flutter/src/rendering/object.dart:1858:7)
#108    RenderProxyBoxMixin.performLayout (package:flutter/src/rendering/proxy_box.dart:116:14)
#109    RenderObject.layout (package:flutter/src/rendering/object.dart:1858:7)
#110    RenderProxyBoxMixin.performLayout (package:flutter/src/rendering/proxy_box.dart:116:14)
#111    RenderObject.layout (package:flutter/src/rendering/object.dart:1858:7)
#112    RenderProxyBoxMixin.performLayout (package:flutter/src/rendering/proxy_box.dart:116:14)
#113    RenderObject.layout (package:flutter/src/rendering/object.dart:1858:7)
#114    RenderProxyBoxMixin.performLayout (package:flutter/src/rendering/proxy_box.dart:116:14)
#115    RenderObject.layout (package:flutter/src/rendering/object.dart:1858:7)
#116    RenderProxyBoxMixin.performLayout (package:flutter/src/rendering/proxy_box.dart:116:14)
#117    RenderObject.layout (package:flutter/src/rendering/object.dart:1858:7)
#118    RenderProxyBoxMixin.performLayout (package:flutter/src/rendering/proxy_box.dart:116:14)
#119    RenderObject.layout (package:flutter/src/rendering/object.dart:1858:7)
#120    RenderProxyBoxMixin.performLayout (package:flutter/src/rendering/proxy_box.dart:116:14)
#121    RenderObject.layout (package:flutter/src/rendering/object.dart:1858:7)
#122    RenderProxyBoxMixin.performLayout (package:flutter/src/rendering/proxy_box.dart:116:14)
#123    RenderOffstage.performLayout (package:flutter/src/rendering/proxy_box.dart:3422:13)
#124    RenderObject.layout (package:flutter/src/rendering/object.dart:1858:7)
#125    RenderProxyBoxMixin.performLayout (package:flutter/src/rendering/proxy_box.dart:116:14)
#126    RenderObject.layout (package:flutter/src/rendering/object.dart:1858:7)
#127    _RenderTheatre.performLayout (package:flutter/src/widgets/overlay.dart:745:15)
#128    RenderObject.layout (package:flutter/src/rendering/object.dart:1858:7)
#129    RenderProxyBoxMixin.performLayout (package:flutter/src/rendering/proxy_box.dart:116:14)
#130    RenderObject.layout (package:flutter/src/rendering/object.dart:1858:7)
#131    RenderProxyBoxMixin.performLayout (package:flutter/src/rendering/proxy_box.dart:116:14)
#132    RenderObject.layout (package:flutter/src/rendering/object.dart:1858:7)
#133    RenderProxyBoxMixin.performLayout (package:flutter/src/rendering/proxy_box.dart:116:14)
#134    RenderObject.layout (package:flutter/src/rendering/object.dart:1858:7)
#135    RenderProxyBoxMixin.performLayout (package:flutter/src/rendering/proxy_box.dart:116:14)
#136    RenderObject.layout (package:flutter/src/rendering/object.dart:1858:7)
#137    RenderProxyBoxMixin.performLayout (package:flutter/src/rendering/proxy_box.dart:116:14)
#138    RenderObject.layout (package:flutter/src/rendering/object.dart:1858:7)
#139    RenderProxyBoxMixin.performLayout (package:flutter/src/rendering/proxy_box.dart:116:14)
#140    RenderObject.layout (package:flutter/src/rendering/object.dart:1858:7)
#141    RenderProxyBoxMixin.performLayout (package:flutter/src/rendering/proxy_box.dart:116:14)
#142    RenderObject.layout (package:flutter/src/rendering/object.dart:1858:7)
#143    RenderView.performLayout (package:flutter/src/rendering/view.dart:165:14)
#144    RenderObject._layoutWithoutResize (package:flutter/src/rendering/object.dart:1713:7)
#145    PipelineOwner.flushLayout (package:flutter/src/rendering/object.dart:885:18)
#146    RendererBinding.drawFrame (package:flutter/src/rendering/binding.dart:453:19)
#147    WidgetsBinding.drawFrame (package:flutter/src/widgets/binding.dart:883:13)
#148    RendererBinding._handlePersistentFrameCallback (package:flutter/src/rendering/binding.dart:319:5)
#149    SchedulerBinding._invokeFrameCallback (package:flutter/src/scheduler/binding.dart:1143:15)
#150    SchedulerBinding.handleDrawFrame (package:flutter/src/scheduler/binding.dart:1080:9)
#151    SchedulerBinding._handleDrawFrame (package:flutter/src/scheduler/binding.dart:996:5)
#155    _invoke (dart:ui/hooks.dart:166:10)
#156    PlatformDispatcher._drawFrame (dart:ui/platform_dispatcher.dart:270:5)
#157    _drawFrame (dart:ui/hooks.dart:129:31)
(elided 5 frames from class _AssertionError and dart:async)
====================================================================================================
flutter pull-to-refresh
8个回答
3
投票

Widget build(Context context) 中初始化的 RefreshController 和 onRefresh 函数...。像这样

//这是我的项目代码

@override
  Widget build(BuildContext context) {
    
    final RefreshController homeRefreshController = RefreshController();

    void onRefresh() async {
      try {
        await _homeController.getDashbaordInfo();
        homeRefreshController.refreshCompleted();
      } catch (e) {
        homeRefreshController.refreshFailed();
      }
    }

...

它对我有用。


1
投票

我在选项卡视图中使用 SmartRefresher,因此当我导航到所有选项卡都在那里的 MainActivity 时,SmartRefresher 会给出相同的错误。

这是因为 SmartRefresher 失去了状态。

解决方案: 像这样初始化 SmartRefresher :

RefreshController refreshController = RefreshController(initialRefresh: false);

在我的情况下,当用户注销并再次登录时,mainactivity 会给出错误,因为当我使用 getx 时它正在获取先前的状态,但 smartrefresher 已丢失其状态。所以要解决这个问题:

  logoutUser() async {
  Get.offAllNamed(Routes.ONBOARDING_SCREEN);
}

0
投票
final _refreshControllers = <RefreshController>[
  RefreshController(...),
  RefreshController(...),
  RefreshController(...)
];

只需为每个 SmartRefresher 创建多个 RefreshController 实例。


0
投票

我通过制作解决了这个问题

class HomeCubit extends Cubit<HomeState> {
  HomeCubit() : super(HomeInitial());

  static HomeCubit get(context) => BlocProvider.of(context);

   late RefreshController refreshController;

}

在我的逻辑类和小部件类中

  @override
  void initState() {
    HomeCubit.get(context).refreshController = RefreshController(initialRefresh: false);
    super.initState();
  }

0
投票
SmartRefresher(controller: RefreshController(), child:YourWidget() )

让你的控制器不再失去状态,欢迎


0
投票

这是因为您对两个或多个 SmartRefresher 小部件使用了相同的 RefreshController。


0
投票

我用这个解决了

  late RefreshController refreshController;

  @override
  void onInit() {
    refreshController = RefreshController(initialRefresh: false);`
    super.onInit();
  }

0
投票

这意味着您有多个 SmartRefresher() 小部件。但使用一个 RefreshController()。

要解决这个问题,您必须为每个 SmartRefresher 创建 RefreshController()。

© www.soinside.com 2019 - 2024. All rights reserved.