如何解决如果向下滑动以关闭,则 Flutter GestureDetector
我希望能够向下滑动以关闭,但使用 Hero-Animation
。
我尝试使用这样的 GestureDetector
:
body: GestureDetector(
onVerticalDragDown: (details) {
Navigator.pop(context);
},child:
动画看起来不错,但问题是它几乎在任何手势下都是 poping
。我想要的是它只有在用户实际向下滑动时才会弹出。
还应该有一些 finished
属性,以便在用户没有完全向下滑动时取消动画。这是可能的,如果是,如何?我找不到关于此的任何内容..
想要的结果应该是这样的:
如您所见,我可以向下滑动,也可以通过不完全向下滑动来取消 pop
。
当前动画:
通过单击关闭按钮,动画效果很好。
但是如果我开始拖动,动画应该开始,如果我结束它,它应该pop
,或者我也可以取消动画并且动画恢复到正常屏幕。
Widget build(BuildContext context) {
return Scaffold(
body: GestureDetector(
onVerticalDragDown: (details) {
Navigator.pop(context);
},child: Stack(
children: [
Hero(
tag: month.name + 'background',// transitionOnUserGestures: true,child: Container(
// color: CustomColors.darkCustom,decoration: Boxdecoration(
color: CustomColors.darkCustom,borderRadius: BorderRadius.circular(30.0),),Positioned(
right: 30,top: 15,child: SafeArea(
child: Hero(
// transitionOnUserGestures: true,tag: month.name + 'close',child: Container(
height: 45,width: 45,child: RawMaterialButton(
fillColor: CustomColors.lightGreyCustom,splashColor: Colors.transparent,highlightColor: Colors.transparent,// elevation: 10,shape: CircleBorder(),onpressed: () {
Navigator.of(context).pop();
},child: SvgPicture.asset('assets/images/close.white.svg',height: 25,width: 25),Column(
crossAxisAlignment: CrossAxisAlignment.center,children: [
SafeArea(
bottom: false,child: SizedBox(height: 20),Row(
children: [
Padding(
padding:
const EdgeInsets.only(left: 45,top: 45,bottom: 35),child: Hero(
// transitionOnUserGestures: true,tag: month.name + 'text',// sized Box to prevent flickering bug
child: SizedBox(
height: 40,width: 200,// material is need for Hero + Text
child: Material(
color: Colors.transparent,child: Text(
month.name,style: TextStyle(
color: Colors.white,fontSize: 28,fontFamily: Fonts.glossAndBloom,],Hero(
tag: month.name + 'frame',child: Container(
height: Constants.width(context) - 60,width: Constants.width(context) - 60,decoration: Boxdecoration(
borderRadius: BorderRadius.circular(10.0),border: Border.all(color: Colors.white,width: 5),)
],);
}
在 Swift 中,我设法使用以下代码实现了动画:
@objc private func handlePan(gestureRecognizer:UIPanGestureRecognizer) {
// calculate the progress based on how far the user moved
let translation = pangr.translation(in: nil)
let progress = translation.y / 2 / view.bounds.height
switch pangr.state {
case .began:
// begin the transition as normal
self.dismissView()
break
case .changed:
Hero.shared.update(progress)
default:
// finish or cancel the transition based on the progress and user's touch veLocity
if progress + pangr.veLocity(in: nil).y / view.bounds.height > 0.3 {
self.dismissView()
Hero.shared.finish()
} else {
Hero.shared.cancel()
}
}
}
解决方法
我建议使用回调函数的 DragEndDetails。 简单的例子是:
onVerticalDragEnd: (endDetails) {
double velocity = endDetails.primaryVelocity;
if (velocity > 0 ){
Navigator.pop(context);
}
},
在这种情况下,如果您在最后按住拖动手势,它不会弹出,因为速度将等于 0。
编辑:
这是在拖动细节上实现动画的简单示例。在 DragUpdate 容器高度将被调整,但限制为 max:300 到 min:100。在 DragEnd 上,取决于您向上或向下滑动,容器高度将设置为最大或最小。
class AnimatedContainerApp extends StatefulWidget {
@override
_AnimatedContainerAppState createState() => _AnimatedContainerAppState();
}
class _AnimatedContainerAppState extends State<AnimatedContainerApp> {
double height = 300;
bool gestureUp = false;
@override
Widget build(BuildContext context) {
final maxHeight = 300.0;
final minHeight = 100.0;
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text('AnimatedContainer Demo'),),body: Align(alignment: Alignment.bottomCenter,child:AnimatedContainer(
color: Colors.red,height: height,duration: Duration(milliseconds: 200),curve: Curves.fastOutSlowIn,child: GestureDetector(
onVerticalDragUpdate: (details) {
setState((){
if (0 < details.delta.dy)
gestureUp = false;
else
gestureUp = true;
height -= details.delta.dy;
if (height > maxHeight)
height = maxHeight;
else if (height < minHeight)
height = minHeight;
});
},onVerticalDragEnd: (details) {
setState((){
if (gestureUp) {
height = maxHeight;
} else {
height = minHeight;
}
});
},)
),);
}
}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。