我已经在其他平台(特别是iPhone / iPad)上看到了这个,但是无法为Android找到它/它的数字,其他平台似乎没有那么多问题
我有一个拥有多人游戏组件的游戏,其中两个玩家必须同时按下同一屏幕上的按钮。除了同时按下按钮外,其他所有内容都已完成。
截至目前,似乎Android调用了按钮的onTouchEvent,并且由于它被处理,因此它不会调用另一个按钮。你是否认为让它调用两个按钮(如果触摸位于按钮区域内)会起作用?还有其他方法可以实现吗?
感谢您的时间。
Anwser:
我最终在Activity的onTouchEvent函数中实现了两个不同的触摸点。
基本实施:
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只是Button的扩展版本,其中存在一个方法ignoreMotionEvent,这只是设置一个布尔值,确定CustomButton的onTouchEvent函数是立即返回false还是调用super.onTouchEvent。
不幸的是,如果您尝试此代码,它将无法正常工作。那为什么要提呢呢?这是代码的基本概要。我遇到的问题是在Android 1.6及更早版本中不存在使这项工作成功的功能。需要Eclair和更高才能完成这项工作。
现在只是为了帮助其他任何发现这个问题的人,因为他们有同样的问题,这里几乎是我正在运行的内容的精确副本:
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值并将其与Eclair(5)和Froyo(8)进行比较以获得相应的函数。
此外,它还要求您使用2.2或更高版本进行编译。如果您不知道,只要您因版本差异检查缺少的功能,Android就可以向后兼容。这意味着虽然您正在使用2.2进行编译,但它将一直工作到1.0。
这就是我使用的东西,希望它可以帮助别人。
答案 0 :(得分:0)
如果你有两个不同的按钮,你可以将onTouchListeners附加到每个按钮,然后让onTouch调用向你的主活动发送一条消息,指示该按钮被按下了。大致是:
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
}
}
}
(以上代码未经过测试或完整。)
如果您让他们在单个视图上触摸两个不同的点,您可以使用event.getX(index)和event.getY(i)迭代事件。请参阅event.getPointerCount()。 (对不起,这个没有示例代码,主要是因为我认为两个不同的按钮方法更好。:))
答案 1 :(得分:0)
尝试我的MultitouchActivity http://www.passsy.de/multitouch-for-all-views/