MotionEvent问题 [英] MotionEvent Issues

查看:95
本文介绍了MotionEvent问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想知道如何得到准确,得到(x)和获得(Y)值的MotionEvent?正在发生的事情是,当我接触的特定区域在屏幕上,我告诉一个动作发生。 现在的问题是,一旦我触摸屏幕,并把我的手指离开,但它仍然认为我的手指是在同一位置(因为这是最后的位置我感动)。所以,当我有一个以上的羽绒服事件(多点触控),它抛出一切都关掉。有没有一种方法可以重设X和Y值,所以当我放过屏幕,他们回去为0或空(或其他)?

I was wondering how to get accurate, get(x) and get(y) values for a MotionEvent? What is happening is that when I touch a specific area on the screen, I tell an action to happen. The problem is that once I touch the screen and take my finger off, it still thinks my finger is at the same location (since that was the last location I touched). So when I have more than one Down event (for multitouch) it throws everything off. Is there a way to reset the X and Y values so when I let off the screen, they go back to 0 or null (or whatever)?

下面是我刚刚上传,以便更好地解释它的视频,因为它是一种混淆

Here is a video I just uploaded to explain it better, cause it is kind of confusing

http://www.youtube.com/watch?v=OHGj2z5SwQs

这里是确切的code我用

And here is the exact code I'm using

    int x = (int) e.getX();
    int y = (int) e.getY();
    int x2 = (int) e.getX(1);
    int y2 = (int) e.getY(1);


    boolean a1 = y > 0 && y < 200....etc        

    boolean a5 = etc... 

    switch (e.getActionMasked()) {
    case MotionEvent.ACTION_DOWN:
        x =  0;
        y = 0;          
        x2 = 0;
        y2 = 0;
                    ////I'm setting the x and y values to 0 as suggested

        text.setText("x:" + String.valueOf(x) + "y:" + String.valueOf(y));
                    //// This is so I can see the values on the screen
        if (a1 && a5){
            viewA1.setBackgroundColor(Color.GREEN);
            viewA5.setBackgroundColor(Color.GREEN);
        }
        if (a1) {

            viewA1.setBackgroundColor(Color.GREEN);
        }



        else if (a5) {
            viewA5.setBackgroundColor(Color.GREEN);

        }           



        break;

    case MotionEvent.ACTION_POINTER_1_DOWN:
        // /A Strummer
        x =  0;
        y = 0;

        x2 = 0;
        y2 = 0;

        text1.setText("x:" + String.valueOf(x2) + "y:" + String.valueOf(y2));
        if (a1 && a5){

            viewA1.setBackgroundColor(Color.GREEN);
            viewA5.setBackgroundColor(Color.GREEN);

        }
        if (a1) {

            viewA1.setBackgroundColor(Color.GREEN);
        }



        else if (a5) {

            viewA1.setBackgroundColor(Color.GREEN);

        }       
     /////I have pretty much the same method for ACTION_UP & ACTION_POINTER_UP; I set x & y to 0.

请让我知道如果你能想到的任何东西。我想你们解释的方法和它似乎像它会帮助,但它不是。

Please let me know if you can think of anything. I tried the methods you guys explained and it would seem like it would help, but it hasn't.

推荐答案

我没有小费,但一个有效的解决方案和多点触控初学者的一些技巧。我从来没有说我以前看到这样的问题后,急于现在怎么多点触控的作品。而实际上它是pretty的技巧把它做对。这是startes一个很好的例子(视图,当其中一个指针触碰它是有色四个角落 - 一个最多五个指针/指工作)。因此,我将解释它根据工作的解决方案发布进一步说明。

I don't have a tip but a working solution and some tips for multitouch starters. I never did that before so after seeing your question I was eager to now how multitouch works. And actually it's pretty tricky to get it done right. This is a great example for startes (view with four corners which are colored when one of the pointers is touching it - works with one up to five pointers / fingers). So I will explain it based on the working solution posted further below.

基本上它的工作原理是这样的: getPointerCount()< /一>是给当前触摸指针,你的量。 的getX(我)和的的getY(我)是给你相应的坐标。但是,这部分是棘手:指针0,1,2是感人,你举起1(食指),现在你有0,1。这是点的 getPointerId(1)将返回2,因为这仍然是你的指针2这是感人,但它现在的位置1而不是2。你有一个机会,对这种变化做出反应,这时候 ACTION_POINTER_UP 被激发。在此行动,并在 ACTION_POINTER_DOWN getActionIndex()将返回行动指针的位置的对其中添加或指针事件列表中删除指针。否则,它的返回总是0,这件事情没有人告诉你。

Basically it works like this: getPointerCount() is giving you the amount of currently touching pointers. getX(i) and getY(i) are giving you the corresponding coordinates. But this part is tricky: pointer 0, 1, 2 are touching, you lift 1 (second finger), and now you have 0, 1. This is the point where getPointerId(1) will return 2 because this is still your pointer 2 which is touching but it's now on position 1 instead 2. You have a single chance to react on that change, that's when ACTION_POINTER_UP is fired. On this action and on ACTION_POINTER_DOWN getActionIndex() will return the action pointer position of the pointer which was added or removed from pointer event list. Otherwise it's returning always 0 and that's something nobody tells you.

结论是:你无法跟踪其指针移动的(这就是为什么的 getActionIndex()是在移动回0)。这似乎是可笑的逻辑,因为这将是愚蠢的火5每个手指单独的事件。但用多点触控,这是一个真正的不平凡的事实,同时, - )

The conclusion is that you can't actually track which pointer is moving (that's why getActionIndex() is return 0 on move). That seems ridiculously logical because it would be stupid to fire 5 separate events for each finger. But while starting with multitouch that's a really non trivial fact ;-)

下面的例子。 coordsX coordsY 将跟踪指针坐标,如果位置2包含有效的坐标,这意味着,这是你的第三个手指这仍然是触摸屏幕,你是否解除了其他手指与否。这可能是不相关的在这种情况下,但它是一个事实,它仍然可以在其他的多点触控实现有用的。

Here's the example. coordsX and coordsY will track the pointer coordinates and if position 2 contains valid coordinates, it means that this is your third finger which is still touching the screen whether you lifted the other fingers or not. This might not be relevant in this case but it's a fact which could still be useful in other multitouch implementations.

public class MultitouchView extends LinearLayout {

    // we have a maximum of 5 pointer
    // we will set Integer.MIN_VALUE if the pointer is not present
    private int [] coordsX = new int [5];
    private int [] coordsY = new int [5];

    // add 4 views with a certain gravity so they are placed in corners
    public MultitouchView(Context context, AttributeSet attrs) {
        super(context, attrs);

        // initialize as not present
        Arrays.fill(coordsX, Integer.MIN_VALUE);
        Arrays.fill(coordsY, Integer.MIN_VALUE);


        /* the layout is inflated from a XML file and is basically this one:
         * all subviews are matching / filling parent and have a weight of 1
         * <LinearLayout vertical>
         *   <LinearLayout horizontal>
         *     <View /><View />
         *   </LinearLayout>
         *   <LinearLayout horizontal>
         *     <View /><View />
         *   </LinearLayout>
         * </LinearLayout>
         */
    }

    @Override
    public boolean onTouchEvent(MotionEvent e) {
        if (e.getAction() == MotionEvent.ACTION_CANCEL) {
            // every touch is going to be canceled, clear everything
            Arrays.fill(coordsX, Integer.MIN_VALUE);
            Arrays.fill(coordsY, Integer.MIN_VALUE);
        } else {
            // track all touches
            for (int i = 0; i < e.getPointerCount(); i++) {
                int id = e.getPointerId(i);

                if (e.getActionIndex() == i
                        && (e.getActionMasked() == MotionEvent.ACTION_POINTER_UP
                        || e.getActionMasked() == MotionEvent.ACTION_UP)) {
                    // pointer with this id is about to leave, clear it
                    coordsX[id] = coordsY[id] = Integer.MIN_VALUE;
                } else {
                    // update all other pointer positions
                    coordsX[id] = (int) e.getX(i);
                    coordsY[id] = (int) e.getY(i);
                }
            }
        }

        int hw = getWidth() / 2;
        int hh = getHeight() / 2;

        // first no corner is touched
        boolean topLeft = false, topRight = false, bottomRight = false, bottomLeft = false;

        // check if any of the given pointer is touching a certain corner
        for (int i = 0; i < coordsX.length; i++) {
            // pointer is not active (anymore)
            if (coordsX[i] == Integer.MIN_VALUE || coordsY[i] == Integer.MIN_VALUE) {
                continue;
            }

            topLeft = topLeft || coordsX[i] < hw && coordsY[i] < hh;
            topRight = topRight || coordsX[i] > hw && coordsY[i] < hh;
            bottomRight = bottomRight || coordsX[i] > hw && coordsY[i] > hh;
            bottomLeft = bottomLeft || coordsX[i] < hw && coordsY[i] > hh;
        }

        // set the result we have now to the views represnting the corners
        ((ViewGroup) getChildAt(0)).getChildAt(0).setBackgroundColor(topLeft ? 0xffffff00 : 0x0);
        ((ViewGroup) getChildAt(0)).getChildAt(1).setBackgroundColor(topRight ? 0xffff0000 : 0x0);
        ((ViewGroup) getChildAt(1)).getChildAt(0).setBackgroundColor(bottomLeft ? 0xff00ff00 : 0x0);
        ((ViewGroup) getChildAt(1)).getChildAt(1).setBackgroundColor(bottomRight ? 0xff0000ff : 0x0);

        return true;
    }
}

这篇关于MotionEvent问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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