我如何可以通过触摸监听器自定义视图拖放? [英] How can i pass Touch Listeners to Custom View for Drag and Drop?

查看:132
本文介绍了我如何可以通过触摸监听器自定义视图拖放?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有关于办理触摸事件的问题 CustomView .I'm添加自定义视图的动态布局(即的FrameLayout)。有touchListeners在角落拉点这些自定义视图(它显示在下面的图片)。随着,我有拖放总在屏幕上查看,如果用户比角点触摸等(颜色区域在图像中)必须拖放的观点,否则没有,并且如果用户触及之外查看我不想引发任何触摸听众。

I've a question concerning handling touch events for CustomView.I'm adding custom view's dynamically to layout (i.e FrameLayout). Those custom views having touchListeners for pulling points at corners (It shows in the below image). Along with that i have to drag and drop the total view on the screen, if user touches other than those corner points (color area in the image) have to drag and drop of the view otherwise not, and also if user touches outside of that view i don't want trigger any touch listeners.

我能够使用这种code拉这些点

I am able to pull those points by using this code

@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;
}

我怎样才能做到这一点阻力,并与CustomView ....

How can i achieve this drag and drop along with above characters of the CustomView....

推荐答案

我会用一些线性代数来解决这个问题。你有3个或更多点,这是不是线的一部分(线性无关的)。可以利用这一点来确定如果触摸点位于区域内。这变得更加困难了更多的积分你,所以你需要转换的多边形更边角比3下降到一组三角形,采用以下步骤。

I'd use some linear algebra to solve this problem. You have 3 or more points which are not part of a line (linear independent). You could use this fact to determine if the touch point lies within the area. This gets more difficult the more points you have, So you need to transform polygons with more corners than 3 down to a set of triangles, applying the following procedure.

所以,你有三个点A,B,C定义一个三角形。然后定义使用触摸点,以获得方向矢量AT,BT,CT,而A,B,政务司司长表示这三项的触线的基点三行的。

So you have three points A,B,C defining a triangle. Then you define three lines using your touch point to get the direction vectors AT,BT,CT while the A,B,Cs denote the base points of these three touch lines.

然后定义的边界线的AB与基准点A,交流与基准点A(这并不重要,如果A或C为基准点),并在最后的线CB与基C点。所以,让我们总结一下(大字母表示向量,而小写字母表示标量或因素):

Then you define boundary lines AB with the base point A, AC with base point A (it does not matter if A or C is the base point) and at last the line CB with the base point C. So lets summarize (large letters are denoting vectors while small letters are denoting scalars or factors):

边界线

a:X=A+f1*AB
b:X=B+f2*BC
c:X=C+f3*AC

触摸行

ta:X=A+t1*AT
tb:X=B+t2*BT
tc:X=C+t3*CT

现在你与触摸线(粉红在图中)与边界线(绿色/红色)在相反的触线的基点。例如,你需要交叉线'助教'与B线得到交点I3。这一点,你会到达,如果你的程度载体在由系数 T1

Now you intersect the touch lines (pink in in the figure) with the border lines (green/red) in opposite to base point of the touch line. For example you need to intersect line 'ta' with line b to get intersection point I3. This point you'll reach if you extent the vector AT by the factor t1.

如果该系数 T1 是大于1的接触点T谎言和I3一个线TA之间。如果该系数 T1 比1小牛逼在于该行的部分A-I3之外。

If this factor t1 is greater than 1 the touch point T lies between A and I3 one the line 'ta'. if The factor t1 is lesser than 1 T lies outside of the line part A-I3.

您将不得不这样做三次行结核病和c和TC和。每次我(n)的积分将需要较小的多于一个(其中是n是在{1,2,3})。

You will have to do this three times with line tb and c and tc and a. Each time the I(n) points will need to be lesser than one (where is n is in {1,2,3}).

如果这种情况适用于所有的三个路口的接触点是在三角形内。

If this condition applies for all three intersections your touch point is inside the triangle.

您将得到交点求解方程这些简单的系统:

You will get the Intersection by solving these simple systems of equations:

第一

A+t1*AT = B+f2*BC
<=>
0 = A+t1*AT - B - f2*BC

该系统看起来是这样的(其中X,Y捐赠的具体坐标分量):

This systems looks like this (where x,y donate the specific coordinate component):

0 = xA + t1*(xT-xA) - xB - f2*(xC-xB)
0 = yA + t1*(yT-yA) - yB - f2*(yC-yB)

第二个

B+t2*BT = C+f3*AC
<=>
0 = B+t2*BT - C - f3*AC

第三

C+t3*CT = A+f1*AB
<=>
0 = C+t3*CT - A - f1*AB

解决这三个系统会给你答案,如果点位于区域内与否。 该解决方案需要从0是明显的(如0是唯一的解决方案,您的积分都在同一行 - > 线性依赖的)!

Solving these three systems will give you the answer if a point lies within the area or not. The solution needs to be distinctly from 0 (If 0 is the only solution your points are on the same line -> linear dependent)!

根据您可以转换您的所有对象的坐标。

Based upon that you can translate your all of the coordinates of your object.

正如上面提到的,你需要减少到三角形和这种方法应用到多边形的所有子三角形。如果一个人符合条件(或两个或更多,如果你想实现multitouching)你的触摸为对象范围内。

As mentioned above you'll need to reduce down to triangles and apply this method to all subtriangles of a polygon. If one matches the condition (or two or more if you want to implement multitouching) your touch is within the object area.

这只是三个小的计算和应该被称为在触及事件处理一次。既然你知道你的,你触摸的区域也没有必要做这些计算,同时移动你的手指(S)。

This are just three small computations and should be called in the "Touch-Down" Event Handler once. Since you know your you touched the area there is no need to do all these computations while moving your finger(s).

关于Trianglization 这是一个比较复杂的问题用一句话没有回答。根据你对你不想来处理简单的多边形对方回答的意见,你要处理更复杂的形状组成的多边形。至于例如你的明星造型。在这里,你可以使用上面的方法,你需要自己定义你的三角形。因为它不是简单的知道哪个角落属于脸,哪些不是。

About Trianglization This is a more complex matter not answered in one sentence. According to your comments on the other answer you do not want to handle simple polygons, you want to handle more complex shapes consisting of polygons. As for example your star shape. Here you can just use the method above, you need to define your triangles yourself. Because its not that simple to know which corner belongs to a face and which not.

这是替代的解决方案将是使用所谓的快速赫尔算法生成从点集的凸包。这会给你哪个角落点,你应该使用trianglelize形状的轮廓。如果你有一些无阴影面孔只是处理他们的感动为好,如果你真的想处理所有可能的点集。

An alternate solution would be using the so called Quick Hull algorithm to generate a convex hull from a point set. This will give you the contour of the shape which corner points you should use to trianglelize. If you have some "unshaded" faces just handle them as touched as well, if you really want to handle all possible point sets.

我对你的明星的情况下解决方法:

My Solution in you star case:

  • 定义你秒杀三角形

  • Define you spike triangles

使用我前面提到的上述方法(通过解决一些LSES),以确定是否被触摸或没有。

use the method I mentioned earlier above (by solving some LSEs) to determine if one is touched or not.

对于一切的:

用三角形的外接圆Trianglize它。通过找到三个点限定其中不含有任何其他的轮廓点的圆。所谓 Delaunay三角。 让这个方法找到你的三角形。如果你有一些阴影的区域,你可以定义与性质可触摸的或类似的东西,一个三角形的对象,让如果触摸应如何处理,或不是你的算法知道。

Trianglize it by using circumcircle of a triangle. By finding three points which defining a circle not containing any other contour points. The so called Delaunay Triangulation. Let this method find your triangles. If you have some unshaded areas you could define a triangle object with the property "touchable" or something like that, to let your algorithm know if the touch should be handled or not.

如果您处理和更新设置的三角形正常不应该有任何有关如何处理一个凹状更多的问题。

If you handle and update you set of triangles properly there should be no more questions about how to handle a concave shape.

有关您的五边形尝试以下操作:

For your pentagon try following:

  • 使用快速船体和三角测量方法。

  • use the the quick hull and triangulation method.

如果用户改变一个点的位置,更新三角形

if a user changes a points position, update triangles

获利

这篇关于我如何可以通过触摸监听器自定义视图拖放?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆