android scale标签,android – 在onScale事件之后触发的奇怪的onScroll事件

我有一个使用SimpleOnScaleGestureListener和SimpleOnGestureListener的应用程序.每当我进行捏缩放时,我得到了预期的onScale,但是当我抬起时,我看到一个奇怪的onScroll,它具有从捏拉变焦开始的起始位置和从捏拉变焦结束的结束位置.我的问题是,我可以防止假滚吗?

这是代码:

@Override

public boolean onTouchEvent(MotionEvent event) {

// Log every event.

Log.d(TAG, Here.at() + String.format("Event: %d, Time: %d X: %f, Y: %f",

event.getAction(),

event.getEventTime(),

event.getX(),

event.getY()

));

boolean handled = mScaleDetector.onTouchEvent(event); // This appears to ALWAYS return true (online reference indicated that's what the Android code does).

handled |= mDetector.onTouchEvent(event);

handled |= super.onTouchEvent(event);

return handled;

}

private class ScaleListener extends ScaleGestureDetector.SimpleOnScaleGestureListener {

@Override

public boolean onScaleBegin(ScaleGestureDetector detector) {

// This is required. If absent, the scale gesture never starts.

Log.d(TAG, "In onScaleBegin");

mIgnoreNextDrag = true;

return true;

}

@Override

public boolean onScale(ScaleGestureDetector detector) {

Log.d(TAG, "In onScale");

mTimeScale.doScale(detector.getScaleFactor(), detector.getFocusY());

invalidate();

return true;

}

@Override

public void onScaleEnd(ScaleGestureDetector detector) {

Log.d(TAG, "In onScaleEnd");

}

}

private class GestureListener extends GestureDetector.SimpleOnGestureListener {

@Override

public boolean onScroll(MotionEvent me1, MotionEvent me2, float distanceX, float distanceY) {

Log.d(TAG, String.format("Motion Event 1: %d, Time: %d X: %f, Y: %f",

me1.getAction(),

me1.getEventTime(),

me1.getX(),

me1.getY()

));

Log.d(TAG, String.format("Event 2: %d, Time: %d X: %f, Y: %f",

me2.getAction(),

me2.getEventTime(),

me2.getX(),

me2.getY()

));

return true;

}

@Override

public boolean onSingleTapConfirmed(MotionEvent me) {

// Do tap processing.

return true;

}

@Override

public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {

// TODO: Future feature.

return true;

}

@Override

public boolean onDown(MotionEvent e) {

// This is required. If absent, the scroll gesture never starts.

return true;

}

}

这是LogCat:

13:06:05.885: D/my-tag(4140): In View.onTouchEvent, Event: 0, Time: 183279420 X: 171.761444, Y: 918.160767

13:06:05.895: D/my-tag(4140): In View.onTouchEvent, Event: 261, Time: 183279420 X: 171.761444, Y: 918.160767

13:06:05.895: D/my-tag(4140): In onScaleBegin

13:06:05.895: I/ScaleGestureDetector(4140): TwScaleGestureDetector

13:06:05.915: D/my-tag(4140): In View.onTouchEvent, Event: 2, Time: 183279458 X: 171.761444, Y: 908.474365

13:06:05.915: D/my-tag(4140): In onScale

13:06:06.015: D/my-tag(4140): In View.onTouchEvent, Event: 2, Time: 183279542 X: 174.964783, Y: 857.584717

13:06:06.015: D/my-tag(4140): In onScale

13:06:06.105: D/my-tag(4140): In View.onTouchEvent, Event: 2, Time: 183279641 X: 232.242096, Y: 731.365662

13:06:06.105: D/my-tag(4140): In onScale

13:06:06.215: D/my-tag(4140): In View.onTouchEvent, Event: 2, Time: 183279740 X: 313.564514, Y: 595.412964

13:06:06.215: D/my-tag(4140): In onScale

13:06:06.225: D/my-tag(4140): In View.onTouchEvent, Event: 6, Time: 183279751 X: 313.564514, Y: 595.412964

13:06:06.225: D/my-tag(4140): In onScaleEnd

13:06:06.245: D/my-tag(4140): In View.onTouchEvent, Event: 2, Time: 183279774 X: 333.316528, Y: 487.607422

13:06:06.245: D/my-tag(4140): In onScroll, me1: 0, Time: 183279420 X: 171.761444, Y: 918.160767

13:06:06.245: D/my-tag(4140): In onScroll, me2 2: 2, Time: 183279774 X: 333.316528, Y: 487.607422

13:06:06.255: D/my-tag(4140): In View.onTouchEvent, Event: 2, Time: 183279784 X: 331.539551, Y: 488.496460

13:06:06.265: D/my-tag(4140): In onScroll, me1: 0, Time: 183279420 X: 171.761444, Y: 918.160767

13:06:06.265: D/my-tag(4140): In onScroll, me2 2: 2, Time: 183279784 X: 331.539551, Y: 488.496460

13:06:06.275: D/my-tag(4140): In View.onTouchEvent, Event: 1, Time: 183279794 X: 331.539551, Y: 488.496460

您可以看到第一个事件是第一个手指向下(0 = ACTION_DOWN),然后第二个手指向下(261 = ACTION_POINTER_2_DOWN).然后我们看到来自onScaleBegin调用的日志条目和来自缩放手势检测器本身的日志(不是来自我的代码).在这一点上,我想我可以放心地假设比例手势已经开始.这完全符合预期.

接下来是四个移动事件(2 = ACTION_MOVE),每个事件后面紧跟着onScale的日志条目.这仍然是预期的.

然后我们看到一个指针向上事件(6 = ACTION_POINTER_UP),然后是来自onScaleEnd的日志条目,仍然是AOK! (注意它是6而不是262因为我按照我放下它的顺序抬起我的手指,所以指针1先被抬起,而不是指针2.)

现在奇怪的一点.

我们看到一个移动事件,它被SimpleOnGestureListener中的onScroll拾取.第一个参数me1具有从缩放手势开始之前的第一个向下事件开始的x和y坐标.第二个参数me2具有在缩放手势停止后显然反映位置的坐标.

在这个例子中,实际上第二个移动事件也被解释为滚动手势,再次使用预缩放原点.使用上面的代码,我会在缩放缩放后不同地获得1,2或无滚动事件.

(为了完成LogCat,我们为第二个手指做了最后一个事件(1 = ACTION_UP),日志变得安静.)

我做错了吗?如果SimpleOnScaleGestureListener从isInProgress返回false,我只尝试调用SimpleOnGestureListener,但没有快乐.

有任何想法吗?

在此先感谢您,感谢社区中所有人,感谢我多年来从这个网站获得的大量信息!

解决方法:

我还发现这种特殊的行为构建了具有平移/缩放功能的自定义视图.但经过一番思考,这是我的理由:

在多点触控环境中,每个手指都被注册,并且在某种并行分析中处理它们各自的运动.这允许检测系统可以通过OnGestureListener和OnScaleGestureListener发送的不同触摸事件.

没错,你还不知道.

现在,想想两个探测器的不同行为:

> GestureDetector通过在视图的可视区域范围内只有一根手指的拖动来检测滚动事件.它的模式响应:向下 – 向上拖动.检测到拖动事件时会生成滚动事件.

> ScaleGestureDetector通过两个手指在多点触控环境中发出的两个同时拖动来检测比例事件.它的模式响应:(down1& down2) – (drag1和/或drag2) – (up1或up2).

现在,考虑一个自定义视图,您只需要检测滚动事件(忽略所有其他事件).在这种情况下,滚动事件必须抛开所有其他注意事项,因为您已执行其模式(向下拖动).

当您将这两个探测器组合在一起时,它们会独立运行,因此刻度探测器首先会发射,但是当您抬起第二根手指时,涡旋探测器会发射,因为它会检测到一个手指拖动并完成一个向上的事件!

结论:行为似乎是合理的……但Android可以为同时情况提供一些交叉检测器.

好吧,你可以简单地放一个布尔值来解决问题.我在实现中完成了这个:

>声明一个名为scaling的布尔值

>创建onDown事件(在ACTION_DOWN事件上)以清除缩放

>制作onScale事件以设置缩放比例

>如果缩放标志为true,则使onScroll事件不处理滚动

这对我来说已经有用了.

标签:android,gestures,onscroll

来源: https://codeday.me/bug/20190517/1121847.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Android GestureDetector是一个手势识别器,其中包括滑动手势的监听事件。下面是一个简单的示例代码: ```java public class MainActivity extends AppCompatActivity implements GestureDetector.OnGestureListener { private GestureDetector gestureDetector; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); gestureDetector = new GestureDetector(this, this); } @Override public boolean onTouchEvent(MotionEvent event) { return gestureDetector.onTouchEvent(event); } @Override public boolean onDown(MotionEvent e) { return true; } @Override public void onShowPress(MotionEvent e) { } @Override public boolean onSingleTapUp(MotionEvent e) { return true; } @Override public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) { // 滑动事件,distanceX和distanceY分别表示手指在水平和垂直方向上的滑动距离 return true; } @Override public void onLongPress(MotionEvent e) { } @Override public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) { // 快速滑动事件,velocityX和velocityY分别表示手指在水平和垂直方向上的滑动速度 return true; } } ``` 在这个示例中,我们实现了GestureDetector.OnGestureListener接口,并在onCreate()方法中初始化了GestureDetector对象。然后我们重写了Activity的onTouchEvent()方法,并将MotionEvent事件传递给GestureDetector的onTouchEvent()方法。接着我们重写了接口中的各种监听方法,包括onDown()、onShowPress()、onSingleTapUp()、onScroll()、onLongPress()和onFling()方法。 其中,onScroll()方法和onFling()方法就是滑动事件的监听方法,我们可以在这里处理滑动事件。具体来说,onScroll()方法会在手指滑动屏幕时触发,其中的distanceX和distanceY参数分别表示手指在水平和垂直方向上的滑动距离;而onFling()方法则会在手指快速滑动屏幕时触发,其中的velocityX和velocityY参数分别表示手指在水平和垂直方向上的滑动速度。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值