Я видел это на других платформах (особенно на iPhone / iPad), но не смог найти-выяснить-выяснить для Android, и другие платформы, похоже, не намного продвинулись, чем задавать вопрос.
У меня есть игра, в которой есть многопользовательский компонент, в котором два игрока должны одновременно нажимать кнопки на одном экране.Все, кроме одновременного нажатия кнопок, выполняется.
На данный момент кажется, что Android вызывает кнопку onTouchEvent и, поскольку она обрабатывается, она не вызывает другую кнопку.Как вы думаете, что-то вроде вызова обеих кнопок (если касание находится внутри области кнопки) будет работать?Есть ли какой-нибудь другой способ, которым это могло бы быть реализовано?
Спасибо за ваше время.
Anwser:
В итоге я реализовал две различные точки касания в функции onTouchEvent в Activity.
Базовая реализация:
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, он просто устанавливает логическое значение, определяющее, должна ли функция onTouchEvent CustomButton немедленно возвращать false или вызывать super.onTouchEvent.
К сожалению, если вы попробуете этот код, он не будет работать.Так зачем это упоминать?Это основной набросок кода.Проблема, с которой я столкнулся, заключалась в том, что в Android 1.6 и более ранних версиях этой функции не было.Эклер и выше требуются, чтобы сделать эту работу.
Теперь просто, чтобы выручить любого, кто нашел это, потому что у них была та же самая проблема, вот почти точная копия того, что я бегу:
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.
Это то, что я использую, и, надеюсь, это поможет другим.