我已经在其他平台(尤其是 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。
这就是我使用的,希望它可以帮助其他人。