【问题标题】:catch Android back button event on Flutter在 Flutter 上捕获 Android 后退按钮事件
【发布时间】:2018-10-31 08:07:09
【问题描述】:

有什么方法可以从 Android 后退按钮捕获 onBackPressed 事件?

我尝试了WillPopScope,但我的onWillPop 功能只有在我点击材料返回箭头按钮时才会触发

我是这样说的:

class MyView extends StatelessWidget{

Widget build(BuildContext context) {

    return new WillPopScope(
      onWillPop: () async {
        debugPrint("Will pop");
        return true;
      },
      child: ScopedModel<AppModel>(
      model: new AppModel(),
      child: new Scaffold(......

我需要抓住它,因为不知何故我的屏幕在按下后退按钮时表现不正确,它会弹出屏幕及其下方的屏幕,但不知何故,使用材料后退箭头按钮工作正常。

更新:

代码有效,我的问题不在此屏幕的弹出窗口中,而是在上一个屏幕上,我使用了 2 个 MaterialApp 小部件,不知何故它给出了一种奇怪的行为。

【问题讨论】:

标签: android dart flutter


【解决方案1】:

为了防止导航回WillPopScope是正确的方式,应该如下使用:

class Page2 extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return new WillPopScope(
      child: new Scaffold(
        appBar: new AppBar(
          title: new Text('Page 2'),
        ),
        body: new Center(
          child: new Text('PAGE 2'),
        ),
      ),
      onWillPop: () async {
        return false;
      },
    );
  }
}

Future<T> pushPage<T>(BuildContext context, Widget page) {
  return Navigator.of(context)
      .push<T>(MaterialPageRoute(builder: (context) => page));
}

可以像这样调用页面:

pushPage(context, Page2());

【讨论】:

  • 我试过这个并得到相同的结果,它阻止了从后退箭头导航,但当我按下 Android 后退按钮时无法阻止它
  • @RizkyAndriawan 此代码即使使用硬后退按钮也能正常工作。请先尝试此代码。
  • 如果您只想在返回上一屏幕之前停止进程怎么办?我按照这个例子,我可以停止这个过程,但不能返回
  • 找到了。根据 docs(api.flutter.dev/flutter/widgets/WillPopScope-class.html),要返回上一个屏幕,onWillPop 应该返回 Future(() => true);谢谢
【解决方案2】:

这应该很有帮助。

@override
Widget build(BuildContext context) {
  return WillPopScope(
    onWillPop: () {
      _moveToScreen2(context, );
    },
    child: Scaffold(
      key: _scaffoldKey,
      appBar: AppBar(
        leading: IconButton(
            icon: Icon(Icons.arrow_back),
            onPressed: () {
              _moveToScreen2(context);
            }),
        title: Text("Screen 1"),
      ),
    ),
  );
}

/**
* This is probably too thin to be in its own method - consider using
* `Navigator.pushReplacementNamed(context, "screen2")` directly
*/
void _moveToScreen2(BuildContext context) =>
    Navigator.pushReplacementNamed(context, "screen2");

【讨论】:

  • 使用这种方式点击设备后退按钮时是否可以导航不同的页面?
  • @BloodLoss 是的,你可能需要做的就是将Navigator.pushReplacementNamed(context, Routes.keySignIn); 更改为Navigator.pushReplacementNamed(context, "{your-destination-route-key}");
  • 它正在使用Navigator.pushReplacement()
【解决方案3】:

这段代码对我有用。

我认为可能有两个原因。

  1. WillPopScope 的孩子是脚手架
  2. onWillPop 不返回

    return new WillPopScope(
      onWillPop: () {
        if (!_isOpened) Navigator.pop(context);
      },
      child: new Scaffold(
        key: SharedService.orderScaffoldKey,
        appBar: appBar,
        body: new Builder(
          builder: (BuildContext context) {
            return page;
          },
        ),
      ),
    );
    

【讨论】:

    【解决方案4】:

    使用WillPopScope方法并返回false

    @override
    Widget build(BuildContext context) {
      return WillPopScope(
         onWillPop: () async {
            // Do something here
            print("After clicking the Android Back Button");
            return false;
         },
         child: Scaffold(
           appBar: AppBar(
              title: Text("Handling the back button"),
           ),
           body: Center(
              child: Text("Body"),
           ),
        ),
      );
    }
    

    【讨论】:

      【解决方案5】:

      另一种方法是实现NavigatorObserver并将其链接到MaterialApp

      https://api.flutter.dev/flutter/widgets/RouteObserver-class.html

      你不必使用RouteAware,也可以实现自己的NavigatorObserver

      这就是 Flutter 分析如何自动跟踪屏幕打开/关闭的示例:

              MaterialApp(
                ...
                navigatorObservers: [
                 FirebaseAnalyticsObserver(analytics: analytics),
                ],
              )
      

      FirebaseAnalyticsObserver 扩展了 RouteObserver,它本身实现了 NavigatorObserver

      但是WillPopScope 通常是更简单的解决方案

      【讨论】:

        【解决方案6】:

        这里只是添加一个重要的点。 请注意,使用WillPopScope,我们将失去iOS 上的向后滑动手势。

        参考:https://github.com/flutter/flutter/issues/14203

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2012-04-28
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2014-04-28
          • 2020-07-20
          相关资源
          最近更新 更多