Raj*_*ddy 6 android custom-view ontouchlistener
我有关于处理问题touch events的CustomView.I'm添加自定义视图的动态布局(即FrameLayout里).那些具有touchListeners的自定义视图用于在角落处拉点(如下图所示).除此之外我必须在屏幕上拖放整个视图,如果用户触摸除了那些角点之外(图像中的颜色区域)必须拖放视图,否则不会,以及如果用户触摸到外面查看我不想触发任何触摸侦听器.

我可以使用此代码来提取这些点
@Override
public boolean onTouchEvent(MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
if (topTouchArea.contains(event.getX(), event.getY())) {
currentTouch = TOUCH_TOP;
} else if (RightTouchArea.contains(event.getX(),event.getY())) {
currentTouch = TOUCH_RIGHT;
} else if (LeftTouchArea.contains(event.getX(),event.getY())) {
currentTouch = TOUCH_LEFT;
} else {
return false; //Return false if user touches none of the corners
}
return true;
case MotionEvent.ACTION_MOVE:
switch (currentTouch) {
case TOUCH_TOP:
top.x = event.getX();
top.y = event.getY();
invalidate();
return true;
case TOUCH_RIGHT:
Right.x = event.getX();
Right.y = event.getY();
invalidate();
return true;
case TOUCH_LEFT:
Left.x = event.getX();
Left.y = event.getY();
invalidate();
return true;
}
case MotionEvent.ACTION_UP:
switch (currentTouch) {
case TOUCH_TOP:
top.x = event.getX();
top.y = event.getY();
invalidate();
currentTouch = NONE;
return true;
case TOUCH_RIGHT:
Right.x = event.getX();
Right.y = event.getY();
invalidate();
currentTouch = NONE;
return true;
case TOUCH_LEFT:
Left.x = event.getX();
Left.y = event.getY();
invalidate();
currentTouch = NONE;
return true;
}
return false;
}
return false;
}
Run Code Online (Sandbox Code Playgroud)
如何实现与CustomView的上述字符一起拖放....
我会用一些线性代数来解决这个问题.您有3个或更多不属于直线的点(线性无关).您可以使用此事实来确定触摸点是否位于该区域内.如果你拥有的点数越多,这就变得越困难.所以你需要将具有多于3的角的多边形转换为一组三角形,应用以下过程.
所以你有三个点A,B,C定义一个三角形.然后使用触摸点定义三条线以获得方向向量AT,BT,CT,而A,B,Cs表示这三条触摸线的基点.
然后用基点A 定义边界线 AB,用基点A 定义AC(如果A或C是基点则无关紧要),最后用基点C定义CB线.所以总结(大字母是表示向量而小写字母表示标量或因子):
边界线:
a:X=A+f1*AB
b:X=B+f2*BC
c:X=C+f3*AC
Run Code Online (Sandbox Code Playgroud)
触摸线:
ta:X=A+t1*AT
tb:X=B+t2*BT
tc:X=C+t3*CT
Run Code Online (Sandbox Code Playgroud)

现在,您将触摸线(图中的粉红色)与触摸线基点相反的边界线(绿色/红色)相交.例如,您需要将线"ta"与线b相交以获得交点I3.如果您将向量AT扩展到因子t1,您将达到此点.
如果该因子t1大于1,则触摸点T位于A和I3之间,即"ta"线.如果因子t1小于1T,则位于线部分A-I3之外.
您必须使用行tb和c和tc以及a执行此操作三次.每次I(n)点需要小于1(其中n在{1,2,3}中).
如果此条件适用于所有三个交叉点,则您的触点位于三角形内.
您将通过解决这些简单的方程组来获得交点:
首先
A+t1*AT = B+f2*BC
<=>
0 = A+t1*AT - B - f2*BC
Run Code Online (Sandbox Code Playgroud)
这个系统看起来像这样(其中x,y捐赠特定的坐标组件):
0 = xA + t1*(xT-xA) - xB - f2*(xC-xB)
0 = yA + t1*(yT-yA) - yB - f2*(yC-yB)
Run Code Online (Sandbox Code Playgroud)
第二
B+t2*BT = C+f3*AC
<=>
0 = B+t2*BT - C - f3*AC
Run Code Online (Sandbox Code Playgroud)
第三
C+t3*CT = A+f1*AB
<=>
0 = C+t3*CT - A - f1*AB
Run Code Online (Sandbox Code Playgroud)
如果某个点位于该区域内,解决这三个系统将为您提供答案.解决方案需要与0明显不同(如果0是您的点在同一条线上的唯一解决方案 - > 线性相关)!
基于此,您可以翻译对象的所有坐标.
如上所述,您需要减少三角形并将此方法应用于多边形的所有子三角形.如果符合条件(或者如果要实现多点触控则为两个或更多),则触摸位于对象区域内.
这只是三个小计算,应该在"Touch-Down"事件处理程序中调用一次.由于您知道您触摸了该区域,因此在移动手指时无需进行所有这些计算.
关于Trianglization 这是一个更复杂的问题,一句话没有回答.根据你对另一个答案的评论,你不想处理简单的多边形,你想要处理由多边形组成的更复杂的形状.例如你的星形.在这里你可以使用上面的方法,你需要自己定义三角形.因为知道哪个角落属于一个面而不是哪个角落并不那么简单.
另一种解决方案是使用所谓的Quick Hull算法从点集生成凸包.这将为您提供形状的轮廓,您应该使用三角形的角点.如果您有一些"无阴影"的面孔,只需触摸它们,如果您真的想要处理所有可能的点集.
我的解决方案明星案例:
定义尖峰三角形
使用我前面提到的方法(通过解决一些LSE)来确定是否触摸了一个.
其他一切:
通过使用三角形的外接圆来三角化它.通过找到定义不包含任何其他轮廓点的圆的三个点.所谓的Delaunay三角剖分.让这个方法找到你的三角形.如果你有一些没有阴影的区域,你可以用属性"touchable"或类似的东西来定义一个三角形对象,让你的算法知道是否应该处理触摸.
如果您正确处理和更新三角形组,则不应再有关于如何处理凹形的问题.
对于你的五角大楼尝试以下:
使用快速船体和三角测量方法.
如果用户更改了点位置,则更新三角形
利润
| 归档时间: |
|
| 查看次数: |
2661 次 |
| 最近记录: |