Flutter中如何使用WillPopScope的示例代码
在Flutter中如何实现点击2次Back按钮退出App,如何实现App中多个Route(路由),如何实现Back按钮只退出指定页面,此篇文章将告诉你。
WillPopScope
WillPopScope用于处理是否离开当前页面,在Flutter中有多种方式可以离开当前页面,比如AppBar、CupertinoNavigationBar上面的返回按钮,点击将会回到前一个页面,在Android手机上点击实体(虚拟)返回按钮,也将会回到前一个页面,此功能对于iOS程序员来说可能特别容易忽略。
以下几种情况我们会用到WillPopScope:
- 需要询问用户是否退出。
- App中有多个Navigator,想要的是让其中一个 Navigator 退出,而不是直接让在 Widget tree 底层的 Navigator 退出。
询问用户是否退出
在Android App中最开始的页面点击后退按钮,默认会关闭当前activity并回到桌面,我们希望此时弹出对话框或者给出提示“再次点击退出”,避免用户的误操作。
WillPopScope(
onWillPop: () async = showDialog(
context: context,
builder: (context) =
AlertDialog(title: Text('你确定要退出吗?'), actions: <Widget [
RaisedButton(
child: Text('退出'),
onPressed: () = Navigator.of(context).pop(true)),
RaisedButton(
child: Text('取消'),
onPressed: () = Navigator.of(context).pop(false)),
])),
child: Container(
alignment: Alignment.center,
child: Text('点击后退按钮,询问是否退出。'),
))
我们也可以把效果做成快速点击2次退出:
DateTime _lastQuitTime;
WillPopScope(
onWillPop: () async {
if (_lastQuitTime == null ||
DateTime.now().difference(_lastQuitTime).inSeconds 1) {
print('再按一次 Back 按钮退出');
Scaffold.of(context)
.showSnackBar(SnackBar(content: Text('再按一次 Back 按钮退出')));
_lastQuitTime = DateTime.now();
return false;
} else {
print('退出');
Navigator.of(context).pop(true);
return true;
}
},
child: Container(
alignment: Alignment.center,
child: Text('点击后退按钮,询问是否退出。'),
))
App中有多个Navigator
我们的App通常是在MaterialApp和CupertinoApp下,MaterialApp和CupertinoApp本身有一个Navigator,所以默认情况下调用Navigator.pop或者Navigator.push就是在操作此Navigator。不过在一些情况下,我们希望有自己定义的Navigator,比如如下场景:
- 在页面底部有一个常驻bar,其上展示内容,这个常驻bar就需要一个自己的Navigator。
- 在使用TabView、BottomNavigationBar、CupertinoTabView这些组件时,希望有多个Tab,但每个Tab中有自己的导航行为,这时需要给每一个Tab加一个Navigator。
首页:
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
@override
_MyHomePageState createState() = _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage {
GlobalKey<NavigatorState _key = GlobalKey();
@override
Widget build(BuildContext context) {
return Scaffold(
body: WillPopScope(
onWillPop: () async {
if (_key.currentState.canPop()) {
_key.currentState.pop();
return false;
}
return true;
},
child: Column(
children: <Widget [
Expanded(
child: Navigator(
key: _key,
onGenerateRoute: (RouteSettings settings) =
MaterialPageRoute(builder: (context) {
return OnePage();
}),
),
),
Container(
height: 50,
color: Colors.blue,
alignment: Alignment.center,
child: Text('底部Bar'),
)
],
)),
);
}
}
第一个页面:
class OnePage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Container(
child: RaisedButton(
child: Text('去下一个页面'),
onPressed: () {
Navigator.push(context, MaterialPageRoute(builder: (context) {
return TwoPage();
}));
},
),
),
),
);
}
}
第二个页面:
class TwoPage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Container(
child: Text('这是第二个页面'),
),
),
);
}
}
使用TabView、BottomNavigationBar、CupertinoTabView这些组件时也是一样的原理,只需在每一个Tab中加入Navigator,不要忘记指定key。
总结
到此这篇关于Flutter中如何使用WillPopScope的文章就介绍到这了,更多相关flutter使用WillPopScope内容请搜索ZaLou.Cn以前的文章或继续浏览下面的相关文章希望大家以后多多支持ZaLou.Cn!
- Spring Cloud构建微服务架构:分布式服务跟踪(抽样收集)【Dalston版】
- HBase client访问ZooKeeper获取root-region-server DeadLock问题(zookeeper.ClientCnxn Unable to get data of zn
- zookeeper学习系列:四、Paxos算法和zookeeper的关系
- 有了phonegap你还android吗?
- zookeeper学习系列:三、利用zookeeper做选举和锁
- Spring Cloud构建微服务架构:分布式服务跟踪(收集原理)【Dalston版】
- zookeeper学习系列:二、api实践
- Spring Cloud构建微服务架构:分布式服务跟踪(整合logstash)【Dalston版】
- Spring Cloud构建微服务架构:分布式服务跟踪(整合zipkin)【Dalston版】
- 困扰我多年的Connection reset问题
- scala学习笔记
- jersey处理支付宝异步回调通知的问题:java.lang.IllegalArgumentException: Error parsing media type 'application/x-www
- 使用 Java Service Wrapper 启动java后台进程服务
- PHP码农在Golang压力下的生存之道-PHP性能优化实践
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- Egg.js试水 - 文章增删改查【前后端分离】
- Flutter基础widgets教程-Offstage篇
- 一份礼物.apk - o泡果奶-的逆向分析
- 代码审计-.NET下的序列化与反序列化(BinaryFormatter)
- 02.视频播放器整体结构
- Spring中@Component和@Bean
- HTTP对接方式
- 使用ShardingSphere 过程中遇到的关于spring boot 版本的问题
- 腾讯云TKE-Pod案例: 容器内crontab问题
- iOS音视频接入 - TRTC多人视频会议
- Spring系列 SpringMVC的请求与数据响应
- codeforces 1349A(数学)
- leetcode之找不同
- 太强了,这居然是19年双非本科开发一年的Android面筋!开发几年的老程序员自叹不如
- Kotlin Vocabulary | Reified: 类型擦除后再生计划