flutterDon‘t use one refreshController to multiple SmartRefresher,It will cause some unexpected bugs
·
flutter pull_to_refresh 结合getx报
Don’t use one refreshController to multiple SmartRefresher,It will cause some unexpected bugs mostly in TabBarView ‘package:pull_to_refresh_flutter3/src/smart_refresher.dart’: Failed assertion: line 548 pos 12: '_refresherState == null
一般这种问题,是因为 Getx的每个GetxController 要对应SmartRefresher 各自独立RefreshController , 如果相同的 我的GetxController 要加tag区分,我的每个GetX对应各自的refreshController,GetxController 是各自的,Getx也加了Tag个,按理说不会有这个问题,正常打开使用没问题,但是当用户按了back键后,在快速点击ListView必报这个,代码如下
///外部传参RefreshController
RefreshController? refreshController;
///子类,必须是ListView-ScrolleView等
Widget? child;
@override
Widget build(BuildContext context) {
return ScrollConfiguration(
behavior: OverScrollBehavior(),
child: SmartRefresher(
key: key,
controller: refreshController ?? controller.refreshController,
enablePullDown: enablePullDown,
enablePullUp: enablePullUp,
onRefresh: () => controller.onLoadRefresh(),
onLoading: () => controller.onLoadMore(),
header: ClassicHeader(
releaseText: ID.releaseText.tr,
refreshingText: ID.refreshingText.tr,
completeText: ID.completeText.tr,
idleText: ID.idleText.tr,
textStyle: TextStyle(
fontSize: Get.setFontSize(14),
fontFamily: Get.setFontFamily(),
fontWeight: FontWeightX.regular,
color: Get.theme.textSecondary,
overflow: TextOverflow.ellipsis),
),
footer: ClassicFooter(
loadingText: ID.loadingText.tr,
idleText: ID.pullUpToLoad.tr,
canLoadingText: ID.canLoadingText.tr,
textStyle: TextStyle(
fontSize: Get.setFontSize(14),
fontFamily: Get.setFontFamily(),
fontWeight: FontWeightX.regular,
color: Get.theme.textSecondary,
overflow: TextOverflow.ellipsis),
noDataText: ID.noDataText.tr,
),
child: child));
}
}
@override
build(BuildContext context) {
return GetBuilder<TokenActivityController>(
id: GetKey.assetsActivityId,
tag: tag,
builder: (controller) {
return controller.obx((state) => buildContent(action!),
onLoading: !controller.hasCache
? const HomeTokeListSkeletonWidget()
: buildContent(action!),
onError: (error) => controller.hasCache
? buildContent(action!)
: AppErrorWidget(onRefresh: () {
controller.showLoading();
controller.loadData();
}),
onEmpty: const AppEmptyWidget());
});
}
buildContent(ActivityAction action) {
if (action == ActivityAction.send && controller.sendDataList.isEmpty) {
return const AppEmptyWidget();
} else if (action == ActivityAction.receive &&
controller.receiveDataList.isEmpty) {
return const AppEmptyWidget();
} else if (action == ActivityAction.resources &&
controller.resourcesDataList.isEmpty) {
return const AppEmptyWidget();
}
return RefreshWidget<TokenActivityController>(
enablePullDown: true,
enablePullUp: false,
controllerTag: tag,
refreshController: controller.refreshController,
child:
CustomScrollView(physics: const BouncingScrollPhysics(), slivers: [
SliverList(
delegate: SliverChildBuilderDelegate((context, index) {
return (controller.dataList.isNotEmpty)
? _itemBuilder(controller.getDataList(action)[index])
: const SizedBox.shrink();
}, childCount: controller.getDataList(action).length)),
footerWidget(),
]));
}
class TokenAssetsBinding extends Bindings {
@override
void dependencies() {
Get.lazyPut(() => TokenAssetsController());
Get.lazyPut(() => TokenActivityController(), tag: "all");
Get.lazyPut(() => TokenActivityController(), tag: "send");
Get.lazyPut(() => TokenActivityController(), tag: "receive");
Get.lazyPut(() => TokenActivityController(), tag: "resources");
}
}
最终解决办法
,因为我页面退出有个300 毫秒的 退出动画,A页面跳转B页面,B页面按了返回键,要退出的一霎那这时候点了B页面,其实是点了A页面,又进入了B,导致Getx持有refreshController 数据紊乱,修改方法 A页面跳转B时加个isClickable 为false ,返回时等待500毫秒才能点击A
return GestureDetector(
onTap: () async {
final nftController = Get.find<NftController>();
// 防止快速点击pull_to_refresh 出现bug
if (!nftController.isClickable.value) {
return;
}
// 禁用点击事件
nftController.isClickable.value = false;
// 导航到详情页面
await toDetails();
// 等待动画结束(假设动画时间为500ms)
await Future.delayed(const Duration(milliseconds: 500));
// 重新启用点击事件
nftController.isClickable.value = true;
},
Future toDetails() async {
await Get.toNamed(AppRoutes.assetsDetailPage, arguments: {
GetArgumentsKey.walletModel: controller.walletModel,
GetArgumentsKey.addressModel: controller.addressModel,
GetArgumentsKey.coinModel: controller.coinModel,
GetArgumentsKey.model: model,
});
}
更多推荐




所有评论(0)