Flutter 无法使用GestureDetector上的longPress可靠地触发动画
我正在尝试创建一个带有进度指示器的按钮(Flutter 无法使用GestureDetector上的longPress可靠地触发动画,flutter,gesturedetector,animationcontroller,Flutter,Gesturedetector,Animationcontroller,我正在尝试创建一个带有进度指示器的按钮(CircularProgressIndicator) 所需流量: 用户点击按钮,它将启动一个功能 用户按下按钮(并按住),它将触发动画并启动一个功能 当用户释放其保持时,应重置动画并启动一个功能 此时,我的代码在第二次按下(并按住)元素时起作用。第一次,动画控制器的addListener打印2-3次,然后停止,而第二次,它保持为true,并在用户持有元素时继续打印。Ontap功能无论如何都可以工作 这是在android和ios设备上本地运行时发生的 剥离代
CircularProgressIndicator
)
所需流量:
导入“包装:颤振/材料.省道”;
导入“package:homi_frontend/constants/woopen_colors.dart”;
类ProgressButton扩展StatefulWidget{
前进按钮({
@需要此.onTap,
@需要这个。onLongPress,
@需要此选项。仅长按向上,
this.duration=const duration(秒:60),
});
最终功能onTap;
最终功能onLongPress;
最终功能仅限长按;
最后期限;
@凌驾
ProgressButtonState createState()=>ProgressButtonState();
}
类ProgressButtonState扩展状态
使用SingleTickerProviderStateMixin{
AnimationController _AnimationController;
bool _beingPressed=false;
@凌驾
void initState(){
_animationController=animationController(
vsync:这个,,
持续时间:widget.duration,
);
_animationController.addListener(_animationListener);
_animationController.addStatusListener(_animationStatusListener);
super.initState();
}
void _animationListener(){
打印(“动画控制器侦听器”);
setState((){});
}
void\u animationStatusListener(AnimationStatus状态){
打印(“动画状态侦听器”);
如果(状态==AnimationStatus.completed){
印刷品(
'完成的持续时间${widget.duration},fire_handleOnLongPressUp');
_handleon longpressup();
}
if(status==AnimationStatus.forward){
此.setState(){
_被按下=正确;
});
}
}
void_handleonglongpress(){
印刷品(“U-handleOnLongPress”);
试一试{
_animationController.forward();
}捕获(e){
打印(“U-handleOnLongPress错误:${e.toString()}”);
}最后{
if(_animationController.status==AnimationStatus.forward){
打印('Controller已启动,fire widget.onLongPress');
widget.onLongPress();
}
}
}
void _handleOnLongPressUp(){
打印(“U-handleOnLongPressUp”);
试一试{
此.setState(){
_被按下=错误;
});
_animationController.reset();
}捕获(e){
打印(“U handleOnLongPressUp错误:${e.toString()}”);
}最后{
如果(_animationController.status==AnimationStatus.discomered){
打印('控制器已被解除,fire widget.onLongPressUp');
widget.onLongPressUp();
}
}
}
@凌驾
处置{
_animationController.dispose();
super.dispose();
}
@凌驾
小部件构建(构建上下文){
返回手势检测器(
key:key('progressButtonGestureDetector'),
行为:HitTestBehavior.不透明,
onLongPress:_handleOnLongPress,
onLongPressUp:_handleOnLongPressUp,
onTap:widget.onTap,
子:容器(
宽度:80,
身高:80,
子级:文本(_animationController.value.toStringAsFixed(2)),
),
);
}
}
输出:
flutter: _handleOnLongPress
flutter: _animationStatusListener
flutter: Controller has been started, fire widget.onLongPress
(2) flutter: Animation Controller Listener
# here it just seems to loose its connection, but if I press (and hold) again, I get:
flutter: _handleOnLongPress
flutter: _animationStatusListener
flutter: Controller has been started, fire widget.onLongPress
(326) flutter: Animation Controller Listener
flutter: _handleOnLongPressUp
flutter: Animation Controller Listener
flutter: _animationStatusListener
flutter: Controller has been dismissed, fire widget.onLongPressUp
我还简要地查看了rawgesturedector
,但只有我的TapGestureRecognizer
手势似乎启动了,LongPressGestureRecognizer
没有。。。即使删除了TapGestureRecognitor
s
_custombiges=Map();
_自定义手势[点击手势识别器]=
手势识别器FactoryWithHandlers(
()=>TapGestureRecognitor(调试所有者:此),
(TapGestureRecognitor实例){
实例
..onTapDown=(tappdown详细信息){
打印('onTapDown');
}
..onTapUp=(TapUpDetails){
打印('onTapUp');
}
…onTap=(){
打印(“onTap”);
}
…onTapCancel=(){
打印(“onTapCancel”);
};
},
);
_自定义手势[长按手势识别器]=
手势识别器FactoryWithHandlers(
()=>长按手势识别器(
持续时间:widget.duration,debugOwner:this),
(LongPressGestureRecognitor实例){
实例
…onLongPress=(){
印刷品(‘onLongPress’);
}
..仅长按开始=(长按开始详细信息){
打印('onLongPressStart');
_animationController.forward();
}
…onLongPressMoveUpdate=(LongPressMoveUpdateDetails详细信息){
打印('onLongPressMoveUpdate');
}
…onLongPressEnd=(LongPressEndDetails){
打印(“仅长按结束”);
_animationController.reset();
}
…onLongPressUp=(){
打印('onLongPressUp');
};
},
);
请&谢谢你的时间 您正在使用
文本
小部件在
GestureDetector
,与拇指相比,它有一个小的点击框。这可能就是为什么你可能偶尔会误点击点击框的原因
您可以使用debugPaintPointersEnabled
更清楚地查看行为(如果应用程序正在运行,则需要进行热重启):
import'package:flatter/rendering.dart';
void main(){
//在这里添加配置
debugPaintPointersEnabled=true;
runApp(App());
}
你可以看到,点击框并不是一直闪烁,即使我们认为我们点击了文本。为了提高准确性,让我们在文本周围环绕一个大小为的容器