为了避免用户误触返回按钮而导致 App 退出,在很多 App 中都拦截了用户点击返回键的按钮,然后进行一些防误触判断,比如当用户在某一个时间段内点击两次时,才会认为用户是要退出(而非误触)。
Flutter中可以通过WillPopScope来实现返回按钮拦截。
1. WillPopScope
WillPopScope 定义
const WillPopScope({
Key? key,
required this.child,
required this.onWillPop,
})
onWillPop是一个回调函数,当用户点击返回按钮时被调用(包括导航返回按钮及Android物理返回按钮)
该回调需要返回一个Future对象,如果返回的Future最终值为false时,则当前路由不出栈(不会返回);最终值为true时,当前路由出栈退出。
2. 示例
为了防止用户误触返回键退出,我们拦截返回事件。当用户在1秒内点击两次返回按钮时,则退出;如果间隔超过1秒则不退出,并重新记时。
class MSWillPopScopeDemo1 extends StatelessWidget {
const MSWillPopScopeDemo1({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text("WillPopScopeDemo1")),
body: Center(
child: ElevatedButton(
onPressed: () {
Navigator.of(context).push(MaterialPageRoute(builder: (ctx) {
return MSWillPopScopTestPage();
}));
},
child: Text("Go To Test")),
),
);
}
}
class MSWillPopScopTestPage extends StatefulWidget {
const MSWillPopScopTestPage({Key? key}) : super(key: key);
@override
State<MSWillPopScopTestPage> createState() => _MSWillPopScopTestPageState();
}
class _MSWillPopScopTestPageState extends State<MSWillPopScopTestPage> {
DateTime? _lastPressTime;
@override
Widget build(BuildContext context) {
return WillPopScope(
onWillPop: () {
print("onWillPop");
if (_lastPressTime == null ||
DateTime.now().difference(_lastPressTime!) > Duration(seconds: 1)) {
//两次点击间隔超过1秒则重新计时
_lastPressTime = DateTime.now();
// false 当前路由不出栈
return Future.value(false);
}
// true 当前路由出栈退出
return Future.value(true);
},
child: Scaffold(
appBar: AppBar(title: Text("Test")),
body: Center(
child: Text("Detail"),
),
),
);
}
}
102.gif
网友评论