Flutter导航返回拦截WillPopScope-监听实体返回键和AppBar返回键Flutter

/ / 2015-10-25
导航返回拦截WillPopScope 为了避免用户误触返回按钮而导致APP退出,在很多APP中都拦截了用户点击返回键的按钮,当用户在某一个时间段内点击两次时,才会认为用户是要退出(而非误触)。Flutter中可以通过WillPopScope来实现返回按钮拦截,我们看看WillPopSc...

导航返回拦截WillPopScope

为了避免用户误触返回按钮而导致APP退出,在很多APP中都拦截了用户点击返回键的按钮,当用户在某一个时间段内点击两次时,才会认为用户是要退出(而非误触)。Flutter中可以通过WillPopScope来实现返回按钮拦截,我们看看WillPopScope的默认构造函数:

const WillPopScope({
  ...
  @required WillPopCallback onWillPop,
  @required Widget child
})

onWillPop是一个回调函数,当用户点击返回按钮时调用(包括导航返回按钮及Android物理返回按钮),该回调需要返回一个Future对象,如果返回的Future最终值为false时,则当前路由不出栈(不会返回),最终值为true时,当前路由出栈退出。我们需要提供这个回调来决定是否退出。


 

WillPopScope 创建的时候需要两个参数 child, onWillPop

onWillPop 就表示当前页面将退出。 值类型是一个函数 typedef Future<bool> WillPopCallback();

WillPopScope(
    onWillPop: (){
        print('onWillPop');
        return Future.value(false);
    },
    child: Container(
        child: Text('haha'),
    ),
),

返回 Future.value(false); 表示不退出.
返回 Future.value(true); 表示退出.

Android 返回按钮点击两次退出应用

  int last = 0;

  Future<bool> doubleClickBack() {
    int now = DateTime.now().millisecond;
    if (now - last > 800) {
      last = DateTime.now().millisecond;
      return Future.value(false);
    } else {
      return Future.value(true);
    }
  }
onWillPop: doubleClickBack,

返回的时候提示弹窗

https://stackoverflow.com/questions/49356664/how-to-override-the-back-button-in-flutter

import 'dart:async';

import 'package:flutter/material.dart';

class HomePage extends StatefulWidget {
  HomePage({Key key, this.title}) :super(key: key);

  final String title;

  @override
  State<StatefulWidget> createState() => new _HomePageState();
}

class _HomePageState extends State<HomePage> {

  Future<bool> _onWillPop() {
    return showDialog(
      context: context,
      builder: (context) => new AlertDialog(
        title: new Text('Are you sure?'),
        content: new Text('Do you want to exit an App'),
        actions: <Widget>[
          new FlatButton(
            onPressed: () => Navigator.of(context).pop(false),
            child: new Text('No'),
          ),
          new FlatButton(
            onPressed: () => Navigator.of(context).pop(true),
            child: new Text('Yes'),
          ),
        ],
      ),
    ) ?? false;
  }

  @override
  Widget build(BuildContext context) {
    return new WillPopScope(
      onWillPop: _onWillPop,
      child: new Scaffold(
        appBar: new AppBar(
          title: new Text("Home Page"),
        ),
        body: new Center(
          child: new Text("Home Page"),
        ),
      ),
    );
  }

1