安卓:同步按钮presses [英] Android: Simultaneous button presses

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

问题描述

我已经看到了这个与其他平台(尤其是iPhone / iPad的),但一直没能找到,它/图,它出Android和其他平台似乎并没有得到太多的更远,然后问的问题

I've seen this with other platforms (especially iPhone/iPad) but have not been able to find-it/figure-it-out for Android and the other platforms don't seem to get much farther then asking the question.

我有一个游戏,有一个多人组成,其中两名球员都preSS按钮在同一时间在同一屏幕上。一切,但同时按钮presses完成。

I have a game that has a multiplayer component where two players have to press buttons on the same screen at the same time. Everything but simultaneous button presses is done.

截至目前好像Android把按钮的的onTouchEvent和,因为它的处理,它不会调用另一个按钮。你觉得像有它调用两个按钮(如果轻轻触摸屏按钮的区域内)会的工作?有没有这个可能可以实现的任何其他方式?

As of right now it seems like Android calls the button's onTouchEvent and, since it is handled, it doesn't call the other button. Do you think something like having it call both buttons (if a touch is within the area of the button) would work? Is there any other way this could possibly be implemented?

感谢您的时间。

Anwser:
我结束了在活动的的onTouchEvent函数实现两个不同的接触点。

Anwser:
I ended up implementing two distinct touch points in the Activity's onTouchEvent function.

基本实现:

public class MainClass extends Activity { 
// ...
btn1 = (CustomButton)findViewById(R.id.button_one);
btn2 = (CustomButton)findViewById(R.id.button_one);
btn1.ignoreMotionEvent(true);
btn2.ignoreMotionEvent(true);
// ...

@Override
public boolean onTouchEvent(MotionEvent event)
{
    if(r1 == null)
    {
        //r1 and r2 are Rect that define the absolute region of the button.
        //They are both defined here to ensure that the everything will be layed out (didn't always work so just for extra "sure-ness" did it here)
    }
    CustomButton btn = null;
    MotionEvent mevent = null;
    switch(event.getAction())
    {
        case MotionEvent.ACTION_DOWN:
        case MotionEvent.ACTION_UP:
            int x = (int)event.getX();
            int y = (int)event.getY();
            if(r1.contains(x, y))
            {
                btn = btn1;
            }
            else if(r2.contains(x, y))
            {
                btn = btn2;
            }
            if(btn != null)
            {
                mevent = event;
            }
            break;
    }
    if(btn != null)
    {
        btn.ignoreMotionEvent(false);
        btn.onTouchEvent(mevent);
        btn.ignoreMotionEvent(true);
    }
    return super.onTouchEvent(event);
}
}

的CustomButton只是按钮,其中一个方法ignoreMotionEvent存在的扩展版本,这只是设置一个布尔值确定的CustomButton的的onTouchEvent函数将返回错误的瞬间或致电super.onTouchEvent。

CustomButton is simply an extended version of Button where a method ignoreMotionEvent exists, this simply sets a boolean determining if CustomButton's onTouchEvent function should return false instantly or call super.onTouchEvent.

不幸的是,如果你尝试这个code这是行不通的。那么,为什么提到它?它是code中的基本轮廓。我遇到的问题是,使这项工作的职能没有在Android 1.6和更早的版本存在。巧克力慕斯蛋糕和更高的要求,使这项工作。

Unfortunately if you tried this code it wouldn't work. So why mention it? It is the basic outline of the code. The issue I encountered was the functions to make this work don't exist on Android 1.6 and earlier. Eclair and higher is required to make this work.

现在只是为了帮助其他任何谁发现了这一点,因为他们有同样的问题,我正在运行什么在这里几乎完全相同的副本:

Now just to help out any other who found this because they had the same issue, here nearly an exact copy of what I am running:

public class MainClass extends Activity { 
// ...
btn1 = (CustomButton)findViewById(R.id.button_one);
btn2 = (CustomButton)findViewById(R.id.button_one);
btn1.ignoreMotionEvent(true);
btn2.ignoreMotionEvent(true);
// ...

@Override
public boolean onTouchEvent(MotionEvent event)
{
    if(r1 == null)
    {
        //r1 and r2 are Rect that define the absolute region of the button.
        //They are both defined here to ensure that the everything will be layed out (didn't always work so just for extra "sure-ness" did it here)
    }
    if(Utils.isEclairOrLater())
    {
        //Eclair and later
        boolean froyo = Utils.isFroyoOrLater();
        int action = froyo ? event.getActionMasked() : event.getAction();
        CustomButton btn = null;
        MotionEvent mevent = null;
        switch(action & MotionEvent.ACTION_MASK)
        {
            case MotionEvent.ACTION_DOWN:
            case MotionEvent.ACTION_UP:
                int x = (int)event.getX();
                int y = (int)event.getY();
                if(r1.contains(x, y))
                {
                    btn = btn1;
                }
                else if(r2.contains(x, y))
                {
                    btn = btn2;
                }
                if(btn != null)
                {
                    mevent = event;
                }
                break;
            case MotionEvent.ACTION_POINTER_DOWN:
            case MotionEvent.ACTION_POINTER_UP:
                int index = froyo ? event.getActionIndex() : ((action & MotionEvent.ACTION_POINTER_ID_MASK) >> MotionEvent.ACTION_POINTER_ID_SHIFT);
                x = (int)event.getX(index);
                y = (int)event.getY(index);
                if(r1.contains(x, y))
                {
                    btn = btn1;
                }
                else if(r2.contains(x, y))
                {
                    btn = btn2;
                }
                if(btn != null)
                {
                    mevent = MotionEvent.obtain(event.getDownTime(), event.getEventTime(), (action & MotionEvent.ACTION_MASK) == MotionEvent.ACTION_POINTER_DOWN ? MotionEvent.ACTION_DOWN : MotionEvent.ACTION_UP, event.getX(index), event.getY(index), 0);
                }
                break;
        }
        if(btn != null)
        {
            btn.ignoreMotionEvent(false);
            btn.onTouchEvent(mevent);
            btn.ignoreMotionEvent(true);
        }
    }
    else
    {
        //Earlier then Eclair
        CustomButton btn = null;
        MotionEvent mevent = null;
        switch(event.getAction())
        {
            case MotionEvent.ACTION_DOWN:
            case MotionEvent.ACTION_UP:
                int x = (int)event.getX();
                int y = (int)event.getY();
                if(r1.contains(x, y))
                {
                    btn = btn1;
                }
                else if(r2.contains(x, y))
                {
                    btn = btn2;
                }
                if(btn != null)
                {
                    mevent = event;
                }
                break;
        }
        if(btn != null)
        {
            btn.ignoreMotionEvent(false);
            btn.onTouchEvent(mevent);
            btn.ignoreMotionEvent(true);
        }
    }
    return super.onTouchEvent(event);
}
}

的Utils是一个简单的工具类的是,对于本实施例的目的,获取Build.VERSION.SDK_INT值,并将其与埃克莱尔(5)和升级Froyo(8),用于相应的功能。

Utils is a simple utility class that, for the purpose of this example, gets the Build.VERSION.SDK_INT value and compares it to Eclair (5) and Froyo (8) for the appropriate functions.

此外,它需要你编译2.2或更高版本。如果你不知道,Android是向后compatable只要你做检查的缺失由于版本的不同功能。这意味着虽然你的编译2.2,将所有的工作方式回到1.0。

Also it requires you compile with 2.2 or higher. If you don't know, Android is backwards-compatable as long as you do the checks for missing functions due to version differences. This means though you are compiling with 2.2, it will work all the way back to 1.0.

这是我使用,希望它可以帮助别人。

That is what I use and hopefully it helps others.

推荐答案

如果你有两个不同的按钮,你可以附加onTouchListeners每个然后有onTouch通话将消息发送到您的主要活动,表明该按钮是pressed。大致是:

If you've got two distinct buttons you could attach onTouchListeners to each and then have the onTouch call send a message to your main activity indicating that the button was pressed. Roughly:

public class MainClass extends Activity implements Handler.Callback {
handler = new Handler(this);
// ...
((Button) findViewById(R.id.button_one)).setOnTouchListener(new OnTouchListener() {
  @Override
  public boolean onTouch(View v, MotionEvent event) {
    handler.sendEmptyMessage(BUTTON_ONE);
    return true;
  }
});
((Button) findViewById(R.id.button_two)).setOnTouchListener(new OnTouchListener() {
  @Override
  public boolean onTouch(View v, MotionEvent event) {
    handler.sendEmptyMessage(BUTTON_TWO);
    return true;
  }
});

public boolean handleMessage(Message msg) {
  if (msg.what == BUTTON_ONE) {
    mButtonOnePressed = System.nanoTime();
    checkIfBothPressed();
  } else if (msg.what == BUTTON_TWO) {
    mButtonTwoPressed = System.nanoTime();
    checkIfBothPressed();
  }
}

public void checkIfBothPressed() {
  if (Math.abs(mButtonOnePressed - mButtonTwoPressed) < 1000000) {
    // They pressed the buttons within one second
  }
}
}

(以上code未经测试或完整。)

(The above code is not tested or complete.)

如果你让他们在一个单一的视图中,可以通过与event.getX(指数)和event.getY(i)该事件重复触摸两个不同点。见event.getPointerCount()。 (对不起,例如code这一块,主要是因为我觉得两个截然不同的,按键的方式比较好。:))

If you're having them touch two distinct points on a single view you can iterate through the events with event.getX(index) and event.getY(i). See event.getPointerCount(). (Sorry, no example code for this one, mainly 'cause I think the two-distinct-buttons approach is better. :) )

这篇关于安卓:同步按钮presses的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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