请稍等 ...
×

采纳答案成功!

向帮助你的同学说点啥吧!感谢那些助人为乐的人

用了手势监听的方式返回上一页,为什么不直接用BackButton,里面也调用了路由ma ymaybePop为什么点击没反应

正在回答

1回答

首先检查一下BackButton所在页面是不是被MaterialApp组件包裹了呢,被MaterialApp包裹的页面是无法通过BackButton组件返回到上一页的,将外层的MaterialApp去掉即可:

 @override
 Widget build(BuildContext context) {
   return MaterialApp(
       ...
       home: Scaffold(
           appBar: AppBar(
           title: Text('BackButton点击没反应'),
             leading: BackButton(),
           ),
          ...
 }
//改成
@override
 Widget build(BuildContext context) {
   return Scaffold(
       appBar: AppBar(
         title: Text('BackButton点击没反应'),
         leading: BackButton()//外层不能有MaterialApp,
       ),
     ...
     }

BackButton被点击的时候会调用maybePop进行返回:

@optionalTypeArgs
Future<bool> maybePop<T extends Object>([ T result ]) async {
 final Route<T> route = _history.last;
 assert(route._navigator == this);
 final RoutePopDisposition disposition = await route.willPop();
 if (disposition != RoutePopDisposition.bubble && mounted) {
   if (disposition == RoutePopDisposition.pop)
     pop(result);
   return true;
 }
 return false;
}

接下来说下一原理:

在上述代码中:

final RoutePopDisposition disposition = await route.willPop();

当BackButton被点击时,会通过route.willPop()决定是否可以返回到上一页,这里我们先看一下willPop()到底做了什么:

Future<RoutePopDisposition> willPop() async {
   return isFirst ? RoutePopDisposition.bubble : RoutePopDisposition.pop;
}

willPop会判断当前页面是不是处于栈顶(当前MaterialApp中的第一个页面),如果是则返回RoutePopDisposition.bubble,所以说只有当前页面不是MaterialApp中的第一个页面时才能通过maybePop返回到上一页,在上述案例中,BackButton被放在了MaterialApp下的第一个页面中所以会出现BackButton点击无效的问题。

接下来在扩充下maybePop与pop的区别,它们的不同之处在于maybePop会多了一步向系统询问是否处理当前返回操作,当Route.willPop返回值为RoutePopDisposition.bubble时即交给系统处理,这里也简单介绍RoutePopDisposition三个枚举值:

  • pop 弹出路由,正常情况返回上一级

  • doNotPop 不弹出,沉默处理,很多时候出现在一些表单填写的情况,必须完成页面内容,或者提示用户点击第二次才能退出

  • bubble 交给系统处理,一般直接退出应用

简单来讲,pop()要比maybePop()的功能更强大些,pop()不管当前页面是不是处于栈顶都会使当前页面关闭,也可以返回到上一个MaterialApp中的页面,而maybePop()只能返回当前MaterialApp中的上一个页面。

注意:pop()这么强大但它有个副作用,如果当前页面已经处于栈顶并且前面没有其他MaterialApp的时候,调用pop()你会看到黑屏,这是因为在这种情况下pop()将应用中的唯一的一个页面关闭导致的,所以为了防止这个问题可以在调用pop()之前通过Navigator.canPop(context)判断下是不是还可以返回。


2 回复 有任何疑惑可以回复我~
  • 提问者 IT小菜 #1
    非常感谢!谢谢老师,等我学到断点那一课时我在断点到源码里看看
    回复 有任何疑惑可以回复我~ 2019-05-15 08:22:54
问题已解决,确定采纳
还有疑问,暂不采纳
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号