首页 > 解决方案 > 有没有一种简单的方法可以使 android 后退按钮的行为与应用栏后退按钮完全一样?

问题描述

我希望硬件后退按钮的行为与我的应用栏后退按钮完全相同。我想要它用于我所有的屏幕。WillPopScope 似乎并不容易使用,因为我的 appbar 将始终是 WillPopScope 的子级,因此对于许多不同的情况,我需要将数据传递给父级。

编辑(更多细节):

在我的应用程序的注册页面中,如果注册过程正在进行中,我将使用 IgnorePointer 阻止用户与应用程序的交互,但这当然不适用于硬件后退按钮。

我还根据注册页面的状态设计了我的 appbar 后退按钮。所以appbar后退按钮至少有3种情况。我也希望所有都适用于硬件后退按钮。问题是我在一个子小部件中,因此我不想为每种情况调用函数并更新父小部件的状态。它没有用,而且做起来很痛苦。

标签: flutter

解决方案


如果我正确理解了你的问题,我有一些东西可以帮助你。我已经在我的一个项目中实现了这段代码。但是,我已经使用ProviderandBloc进行状态管理。

signup_page.dart

@override
  Widget build(BuildContext context) {
    return WillPopScope(
      onWillPop: _onWillPop,
      child: ChangeNotifierProvider<SignupProvider>(
        create: (context) => SignupProvider(),
        child: BlocProvider<SignupBloc>(
          create: (context) => _signupBloc,
          child: BlocListener<SignupBloc, SignupState>(
            listener: (context, state) {
              if (state is SignupCancelled) {
                _closeSignup();
              } else if (state is SignupSuccessful) {
                _closeSignup(delay: 1000);
              } else if (state is SignupInitial) {
                _returnToCredentials();
              } else if (state is SignupProceededToDetails) {
                _proceedToDetails();
              }
            },
            child: Scaffold(
              appBar: AppBar(
                title: const Text("Signup"),
              ),
              body: SafeArea(
                child: PageView(
                  controller: _pageController,
                  physics: const NeverScrollableScrollPhysics(),
                  children: <Widget>[
                    const SignupCredentialsForm(),
                    const SignupDetailsForm(),
                  ],
                ),
              ),
            ),
          ),
        ),
      ),
    );
  }

Future<bool> _onWillPop() async {
    int page = _pageController.page.toInt();

    _signupBloc.add(
      BackButtonPressed(page: page),
    );

    return false;
  }

  _closeSignup({int delay = 0}) async {
    await Future.delayed(Duration(milliseconds: delay));
    Navigator.of(context).pop();
  }

  _returnToCredentials() {
    _pageController.animateToPage(0,
        duration: const Duration(milliseconds: 250), curve: Curves.easeIn);
  }

  _proceedToDetails() {
    _pageController.animateToPage(1,
        duration: const Duration(milliseconds: 250), curve: Curves.easeIn);
  }

如果您查看我的代码,我有一个由 2 页组成的 PageView。PageView 页面都使用 AppBar,并在左上角包含前导后退按钮。

通常情况下,按下应用栏上的返回按钮,或者硬件返回按钮将导致页面关闭,并导航回上一页。

但是,因为我有WillPopScope, on signup_page,所以它被覆盖了。因此,当按下后退按钮(应用程序栏或硬件)时,我能够控制我想要发生的事情。你可以看到,我可以使用 移动到下一个页面视图_proceedToDetails(),或者使用返回到第一个表单_returnToCredentials(),如果我在第一个表单中并且按下后退按钮,则关闭页面,使用_closeSignup()类似地关闭页面,即使当如果注册成功,我在最后一个表格。


推荐阅读