先来认识几个小知识点
flutter官方提供的widget,注册一个异步函数,用于捕获并处理用户的返回键操作(系统提供的返回操作和Navigator.of(context).maybePop()),可以允许或禁止本次操作。我一般是包在Scaffold外面
WillPopScope( onWillPop : () async =>{ // 一些其他操作 return true; } child : Scaffold( body : Container() ); )这个不用过多赘述了,大家用到路由应该都用过,这次我们要用到其中一个静态方法:canPop,这个方法判断路由是否还能返回。
看到这,相信你已经有头绪了,尝试自己试试先敲一下?
没什么用的小技巧
WillPopScope不止可以用在Scaffold上,比如在showDialog中使用,可以阻止用户通过返回键关闭dialog窗口 showDialog( context : context , child : WillPopScope( onWillPop : () async => true , child : SimpleDialog(), ) ) 可以自己包装一个CustomScaffold,这样可以做一些自己的设置,而且可以公用双击退出APP的代码 /// 包装Scaffold /// 添加了安全区 /// 添加了防止元素大小随手机字体大小设置改变 class CustomScaffold extends StatelessWidget { final bool extendBody; final bool extendBodyBehindAppBar; final PreferredSizeWidget appBar; final Widget body; final Widget floatingActionButton; final FloatingActionButtonLocation floatingActionButtonLocation; final FloatingActionButtonAnimator floatingActionButtonAnimator; final List<Widget> persistentFooterButtons; final Widget drawer; final Widget endDrawer; final Color drawerScrimColor; final Color backgroundColor; final Widget bottomNavigationBar; final Widget bottomSheet; final bool resizeToAvoidBottomPadding; final bool resizeToAvoidBottomInset; final bool primary; final DragStartBehavior drawerDragStartBehavior; final double drawerEdgeDragWidth; final bool drawerEnableOpenDragGesture; final bool endDrawerEnableOpenDragGesture; final bool safeArea; CustomScaffold({ Key key, this.appBar, this.body, this.floatingActionButton, this.floatingActionButtonLocation, this.floatingActionButtonAnimator, this.persistentFooterButtons, this.drawer, this.endDrawer, this.bottomNavigationBar, this.bottomSheet, this.backgroundColor, this.resizeToAvoidBottomPadding, this.resizeToAvoidBottomInset, this.primary = true, this.drawerDragStartBehavior = DragStartBehavior.start, this.extendBody = false, this.extendBodyBehindAppBar = false, this.drawerScrimColor, this.drawerEdgeDragWidth, this.drawerEnableOpenDragGesture = true, this.endDrawerEnableOpenDragGesture = true, this.safeArea = true }) : super(key: key); @override Widget build(BuildContext context) { // 退出APP标记 bool isQuit = false; Timer quitTimer; return MediaQuery( data: MediaQuery.of(context).copyWith(textScaleFactor: 1.0), child: WillPopScope( onWillPop: () async { if(!Navigator.canPop(context)){ if(isQuit){ await SystemChannels.platform.invokeMethod('SystemNavigator.pop'); }else{ ToastUtils.showToast(TipsTextConfig.quitApp); isQuit = true; quitTimer = Timer(Duration(seconds: 2) , (){ isQuit = false; quitTimer.cancel(); }); } return false; } return true; }, child: Scaffold( appBar: this.appBar, body: SafeArea( top: safeArea, bottom: safeArea, left: safeArea, right: safeArea, child: this.body, ), floatingActionButton: this.floatingActionButton, floatingActionButtonLocation: this.floatingActionButtonLocation, floatingActionButtonAnimator: this.floatingActionButtonAnimator, persistentFooterButtons: this.persistentFooterButtons, drawer: this.drawer, endDrawer: this.endDrawer, bottomNavigationBar: this.bottomNavigationBar, bottomSheet: this.bottomSheet, backgroundColor: this.backgroundColor, resizeToAvoidBottomPadding: this.resizeToAvoidBottomPadding, resizeToAvoidBottomInset: this.resizeToAvoidBottomInset, primary: this.primary, drawerDragStartBehavior: this.drawerDragStartBehavior, extendBody: this.extendBody, extendBodyBehindAppBar: this.extendBodyBehindAppBar, drawerScrimColor: this.drawerScrimColor, drawerEdgeDragWidth: this.drawerEdgeDragWidth, drawerEnableOpenDragGesture: this.drawerEnableOpenDragGesture, endDrawerEnableOpenDragGesture: this.endDrawerEnableOpenDragGesture, ), ), ); } }