我已经实现了一个ZoomViewGroup
,它能够在所有方向上无限滚动,并且还可以无限缩放,同时仍然可以将所有触摸事件正确地偏移到其子View
s。
但是当谈到多点触控时,只有第一个指针正确偏移,而其他所有指针都指向错误的位置,这就是因为我需要处理缩放因子。 (因为当scaling_factor != 1.0f
)
我正在Matrix
保存转换,因此很容易使用matrix.mapPoints(..)
和矩阵逆来计算从屏幕到工作区的坐标并返回。
当我绘制子视图时,我可以像这样应用变换矩阵:
protected void dispatchDraw(Canvas canvas)
{
canvas.save();
canvas.concat(transformation_matrix);
super.dispatchDraw(canvas);
canvas.restore();
}
与触摸事件相同:
float[] touch_array = new float[2];
public boolean dispatchTouchEvent(MotionEvent event)
{
touch_array[0] = event.getX();
touch_array[1] = event.getY();
transformation_matrix.mapPoints(touch_array);
event.setLocation(touch_array[0], touch_array[1]);
return super.dispatchTouchEvent(event);
}
但是MotionEvent.setLocation(float x, float y)
实际上确实以相同的数量抵消了所有指针。如果我们缩放2.0f,每个指针的偏移量都不同,所以我必须能够为每个指针单独执行MotionEvent.setLoction(int pointer_index, float x, float y)
之类的操作。我能做些什么来实现这个目标吗?
答案 0 :(得分:0)
编辑:到目前为止,我所知道(和搜索过的)唯一的解决方案是使用新坐标创建一个新的MotionEvent。
-
你可以通过getX(int pointerId)/ getY(int)方法得到所有指针(手指触摸)位置。
您可以通过getPointerCount()
获取所有屏幕指针因此,要解析多点触控,您必须执行以下操作:
public boolean dispatchTouchEvent(MotionEvent event)
{
for(int i = 0; i < event.getPointerCount(); i++){
touch_array[0] = event.getX(i);
touch_array[1] = event.getY(i);
transformation_matrix.mapPoints(touch_array);
MotionEvent copy = MotionEvent.obtainNoHistory(event);
copy.setLocation(touch_array[0], touch_array[1]);
boolean handled = super.dispatchTouchEvent(copy);
copy.recycle();
if(handled) return true;
}
return false;
}
另请注意,我创建了一个MotionEvent对象的副本,因此childrem可以修改它而不会破坏for的位置。
抱歉,刚才我注意到你的上一个声明,你必须将事件复制到一个新的MotionEvent,所以childrem可以解析自己并完成它的工作,复制也会使你的代码安全修改,它是一个坏的想要直接更改MotionEvent,因为它可以在任何调度方法中打破for循环。