作为一个炫(pin)酷(ru)的页面,页面中的交互也非常的重要。在本篇,我将进一步说明页面内各个位置的交互细节,从而带着各位做一个不将就的强迫症~
效果图:
完整demo及组件已上传至项目,走过路过留个star~
交互要素
页面中的交互主要包含三个触发位置:点击空白的模糊处,页面会执行退出和退出动画;
点击页面上的返回或关闭按钮,页面会执行退出和退出动画;
元素渐显并带有其他效果。
接下来将逐点说明如何实现。
实现过程
拦截返回操作
我们知道在Flutter中,页面要返回时,会执行Navigator.maybePop的方法,使页面返回。为了拦截路由pop,Flutter提供了WillPopScope来拦截返回行为,我们只需要注册onWillPop方法,就可以在pop前执行代码。bool _popping = false;
Future willPop() async {
/// 等待返回动画的执行
await backDropFilterAnimate(context, false);
/// 判断_popping从而避免重复触发pop
if (!_popping) {
_popping = true;
await Future.delayed(Duration(milliseconds: _animateDuration), () {
Navigator.of(context).pop();
});
}
return null;
}
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.transparent,
body: WillPopScope(
/// 绑定willPop方法
onWIllPop: willPop,
child: wrapper(
context,
child: widget.child,
),
),
);
}
复制代码
如此我们就轻松愉快地拦截了路由~
退出动画
思考退出动画和跳转动画的关系,我们立马就可以想到,跳转和退出的动画是相反的,也就是说,逆向执行跳转的动画,就能得到一个退出动画。
这时我们来回顾一下上一期的跳转动画:void backDropFilterAnimate(BuildContext context) async {
final Size s = MediaQuery.of(context).size;
_backDropFilterController = AnimationController(
duration: Duration(milliseconds: _animateDuration),
vsync: this,
);
Animation _backDropFilterCurve = CurvedAnimation(
parent: _backDropFilterController,
curve: Curves.easeInOut,
);
_backDropFilterAnimation = Tween(
begin: 0.0,
end: pythagoreanTheorem(s.width, s.height) * 2,
).animate(_backDropFilterCurve)
..addListener(() {
setState(() {
_backdropFilterSize = _backDropFilterAnimation.value;
});