flutter:如何在每次用户导航到它时重新加载屏幕

xxhby3vn  于 2023-06-07  发布在  Flutter
关注(0)|答案(1)|浏览(179)

我有一个屏幕,必须重新加载(从API获取新的数据),每次用户导航到(即使当用户按下返回按钮)。
我正在使用riverpod中的AsyncValueGoRouter
这是屏幕代码

class BatchScreen extends ConsumerWidget {
  static const String screenPath = "/BatchScreen";
  const BatchScreen({super.key});

  @override
  Widget build(BuildContext context, WidgetRef ref) {
    final AsyncValue<BatchModel?> btachController =
        ref.watch(batchControllerProvider);
    final AuthRepository authRepository = ref.watch(authRepositoryProvider);
    ref.listen<AsyncValue<void>>(
      batchControllerProvider,
      (_, state) => state.whenOrNull(
        error: (error, stackTrace) {
          // show snackbar if an error occurred
          ScaffoldMessenger.of(context).showSnackBar(
            SnackBar(
              content: Text(
                error.toString(),
              ),
            ),
          );
        },
      ),
    );
    Size size = MediaQuery.of(context).size;
    bool isBegin = false;
    return SafeArea(
      child: Stack(
        children: [
          Scaffold(
            appBar: PreferredSize(
              preferredSize: const Size.fromHeight(250),
              child: CustomeAppBar(
                dynamicWidget: Expanded(
                  flex: 6,
                  child: UserInfo(
                    userId: authRepository.userModel.id,
                    fullName: authRepository.userModel.name,
                    warehouse: 'casablanca',
                  ),
                ),
              ),
            ),
            body: Container(
              alignment: Alignment.center,
              padding: const EdgeInsets.all(16),
              child: Column(
                mainAxisAlignment: (isBegin)
                    ? MainAxisAlignment.spaceAround
                    : MainAxisAlignment.center,
                children: [
                  Column(
                    children: [
                      (isBegin)
                          ? CustomButton(
                              ontap: () {
                                GoRouter.of(context).pushNamed(
                                  APP_PAGE.palettQrCode.toName,
                                );
                              },
                              width: size.width / 1.2,
                              height: size.height / 12,
                              text: context.loc.continuee,
                              colorText: Colors.white,
                              backgroundColor: colorPrimary,
                            )
                          : StartButton(
                              ontap: () {
                                bool test = false;
                                QuickAlert.show(
                                  context: context,
                                  type: QuickAlertType.confirm,
                                  text: 'Do you want to logout',
                                  confirmBtnText: 'Yes',
                                  cancelBtnText: 'No',
                                  confirmBtnColor: Colors.green,
                                  onConfirmBtnTap: () async {
                                    // on error
                                    if (test) {
                                      await QuickAlert.show(
                                        context: context,
                                        type: QuickAlertType.error,
                                        text: 'Please input something',
                                      );
                                      return;
                                    }
                                    Navigator.pop(context);
                                    QuickAlert.show(
                                      context: context,
                                      type: QuickAlertType.loading,
                                      title: 'Loading',
                                      text: 'Fetching your data',
                                      barrierDismissible: false,
                                    );
                                    await Future.delayed(
                                      Duration(milliseconds: 3000),
                                      () async {
                                        if (context.mounted) {
                                          Navigator.pop(context);
                                          GoRouter.of(context).pushNamed(
                                            APP_PAGE.palett.toName,
                                          );
                                        }
                                      },
                                    );
                                  },
                                );
                              },
                            ),
                      const SizedBox(height: 20),
                      if (isBegin)
                        CustomButton(
                          ontap: () {
                            GoRouter.of(context).pop();
                          },
                          width: size.width / 1.2,
                          height: size.height / 12,
                          text: context.loc.close,
                          colorText: Colors.white,
                          backgroundColor: Colors.black,
                          borderColor: Colors.black,
                        ),
                    ],
                  ),
                  if (isBegin)
                    CustomButton(
                      ontap: () {
                        GoRouter.of(context).pop();
                      },
                      width: size.width / 1.2,
                      height: size.height / 12,
                      text: "Abondon",
                      colorText: Colors.red,
                      backgroundColor: Colors.white,
                      borderColor: Colors.red,
                    ),
                ],
              ),
            ),
          ),
          btachController.when(
            data: (data) {
              logDebug(data);
              return const Positioned(
                left: 23,
                top: 200,
                child: BatchProduct(
                  countProduct: 29,
                ),
              );
            },
            error: (error, stackTrace) {
              return Positioned(
                left: 23,
                top: 200,
                child: Container(
                  height: 100,
                  width: size.width / 1.12,
                  decoration: BoxDecoration(
                    color: Colors.white,
                    borderRadius: BorderRadius.circular(10),
                    boxShadow: [
                      BoxShadow(
                        color: Colors.grey.withOpacity(0.4),
                        spreadRadius: 4,
                        blurRadius: 5,
                      ),
                    ],
                  ),
                  child: const Center(
                    child: Text(
                      'Uh oh. Something went wrong!',
                      style: TextStyle(
                        fontSize: 20,
                        color: Colors.black,
                        decoration: TextDecoration.none,
                        fontFamily: 'almarai',
                      ),
                    ),
                  ),
                ),
              );
            },
            loading: () {
              return Positioned(
                left: 23,
                top: 200,
                child: Container(
                  height: 100,
                  width: size.width / 1.12,
                  decoration: BoxDecoration(
                    color: Colors.white,
                    borderRadius: BorderRadius.circular(10),
                    boxShadow: [
                      BoxShadow(
                        color: Colors.grey.withOpacity(0.4),
                        spreadRadius: 4,
                        blurRadius: 5,
                      ),
                    ],
                  ),
                  child: const Center(
                    child: CircularProgressIndicator(),
                  ),
                ),
              );
            },
          ),
        ],
      ),
    );
  }
}

我在用一个控制器来处理所有的功能性工作

class BatchController extends StateNotifier<AsyncValue<BatchModel?>> {
  final BatchRepository batchRepository;
  BatchController({required this.batchRepository})
      : super(const AsyncValue.data(null)) {
    getBatch();
  }

  Future<void> getBatch() async {
    try {
      state = const AsyncValue.loading();

      await Future.delayed(Duration(milliseconds: 2000));
      final List<BatchModel> bacth = await batchRepository.getBatch();
      state = AsyncValue.data(bacth.first);
      logDebug('hello');
      logDebug(state);
    } on DioError catch (e) {
      state = AsyncValue.error(
        "Uh oh. Something went wrong!",
        StackTrace.current,
      );
    }
  }
}

final batchControllerProvider =
    StateNotifierProvider<BatchController, AsyncValue<BatchModel?>>(
  (ref) {
    final batchRepository = ref.read(batchRepositoryProvider);

    return BatchController(batchRepository: batchRepository);
  },
);

问题是当用户第一次在屏幕上着陆时,API调用并获得数据,但是如果用户导航回来或转到新屏幕并回到该屏幕,则用户获得相同的先前数据(而不调用API)。
关键是我想在用户每次登陆这个屏幕时调用一个API。

uinbv5nw

uinbv5nw1#

GoRouter是这样的:
继承对象> ChangeNotifier > GoRouter
这意味着可以通过addListener方法添加所需的操作(当BatchController类不再使用时,可以通过ref.onDispose删除它)。
要点是获取GoRouter的示例,并在类BatchController的初始化中添加一个方法,其中将调用based on the route来更新状态(/data)。
有关更多信息,您可以转到this repository,它为您提供了Riverpod + GoRouter捆绑包的新外观。

相关问题