2013-11-16 3 views
0

Итак, я работаю над игрой, в которой два игрока одновременно играют на одном экране. Для простоты предположим, что у обоих игроков есть одна кнопка на их стороне экрана, кнопки B [0] и B [1]. Я хочу реализовать мультитач, чтобы обе кнопки можно было нажимать без каких-либо проблем, но как только один из них делает ACTION_DOWN на своей кнопке, другой становится невосприимчивым. Я прочитал все повторяющиеся вопросы и понял, что второе касание будет ссылаться как ACTION_POINTER_DOWN поэтому я написал этот кусок кода:Android multitouch issue

@Override 
    public boolean onTouch(View buttonPressed, MotionEvent action) 
    { 
     if(buttonPressed.getId()==B[0].getId()) 
     { 
      if(action.getAction() == MotionEvent.ACTION_DOWN || action.getAction() == MotionEvent.ACTION_POINTER_DOWN) 
       B[0].setImageDrawable(BPressed[0]); 
      if(action.getAction() == MotionEvent.ACTION_UP || action.getAction() == MotionEvent.ACTION_POINTER_UP) 
       B[0].setImageDrawable(BOk[0]);  
     } 
     if(buttonPressed.getId()==B[1].getId()) 
     { 
      if(action.getAction() == MotionEvent.ACTION_DOWN || action.getAction() == MotionEvent.ACTION_POINTER_DOWN) 
       B[1].setImageDrawable(BPressed[1]); 
      if(action.getAction() == MotionEvent.ACTION_UP || action.getAction() == MotionEvent.ACTION_POINTER_UP) 
       B[1].setImageDrawable(BOk[1]);  
     } 
     return true; 
    } 

Так, насколько я могу сказать, если я поставлю 1 палец на B [0] и оставить он там (нет ACTION_UP), а затем положил другого на B [1], слушатель должен запустить onTouch (B [1], ACTION_POINTER_DOWN), но я думаю, что с тех пор, как я это делаю, B [0] имеет Bressed drawable и B [ 1] имеет BOK. Где я неправ? Извините, если я сделал дубликат, но я все прочитал и не могу найти простого решения. Каждое решение по этой проблеме, которое я нашел, дает гораздо больше, чем мне нужно.

Обе кнопки соединены со слушателем, как это:

B[0].setOnTouchListener(this); 
B[1].setOnTouchListener(this); 

Я прочитал это:

ACTION_POINTER_DOWN and ACTION_POINTER_UP are fired whenever a secondary pointer goes down or up. 

Но это не похоже, чтобы быть правдой.

EDIT:

Новый код, все тот же результат:

 @Override 
     public boolean onTouch(View buttonPressed, MotionEvent action) 
     { 
if(buttonPressed.getId()==B[1].getId()) 
      Toast.makeText(context, "One", 500).show(); 
    int act = action.getAction() & MotionEvent.ACTION_MASK; 

      if(buttonPressed.getId()==B[0].getId()) 
      { 
       if(act == MotionEvent.ACTION_DOWN || act == MotionEvent.ACTION_POINTER_DOWN) 
        B[0].setImageDrawable(BPressed[0]); 
       if(act == MotionEvent.ACTION_UP || act == MotionEvent.ACTION_POINTER_UP) 
        B[0].setImageDrawable(BOk[0]);  
      } 
      if(buttonPressed.getId()==B[1].getId()) 
      { 
       if(act == MotionEvent.ACTION_DOWN || act == MotionEvent.ACTION_POINTER_DOWN) 
        B[1].setImageDrawable(BPressed[1]); 
       if(act == MotionEvent.ACTION_UP || act == MotionEvent.ACTION_POINTER_UP) 
        B[1].setImageDrawable(BOk[1]);  
      } 
      return true; 
     } 

Кроме того, тост:

if(buttonPressed.getId()==B[1].getId()) 
     Toast.makeText(context, "One", 500).show(); 

никогда нельзя увидеть, если я держу палец на B [ 0].

После маскирования:

Что-то изменилось. Скажем, я держу палец на B [0]. Перед маскировкой, когда я нажимаю B [1], ничего не происходит. После маскировки, если я держу палец на B [0], и я коснусь пальца НА ЛЮБОЕ на экране, он циклирует B [0]. Так что, если я пойду:

finger1_DOWN on B[0] it changes to Pressed drawable 
while(1) 
{ 
finger2_DOWN anywhere nothing changes 
finger2_UP anywhere B[0] changes to Ok drawable 
} 

Я создаю мой imagebuttons в OnCreate:

B[0] = (ImageButton) findViewById(R.id.ImageButton05); 
B[0].setOnTouchListener(this); 
B[1] = (ImageButton) findViewById(R.id.ImageButton15); 
B[1].setOnTouchListener(this); 

Я попробовал подход jboi в. Я не забочусь, если кнопка была нажата первой или второй, так что я просто сделал это:

private class MPListener implements OnTouchListener 
    { 
     @Override 
     public boolean onTouch(View buttonPressed, MotionEvent event) 
     { 
      if(event.getAction() == MotionEvent.ACTION_DOWN) 
      { 
       if(buttonPressed.getId()==B[0].getId()) 
        B[0].setImageDrawable(BPressed[0]); 

       if(buttonPressed.getId()==B[1].getId()) 
        B[1].setImageDrawable(BPressed[1]); 
      } 
      if(event.getAction() == MotionEvent.ACTION_UP) 
      { 
       if(buttonPressed.getId()==B[0].getId()) 
        B[0].setImageDrawable(BOk[0]); 

       if(buttonPressed.getId()==B[1].getId()) 
        B[1].setImageDrawable(BOk[1]); 
      } 
     return true; 
     } 
    } 

я удалил орудия onTouchListener от моей деятельности и не добавил

B[0].setOnTouchListener(new MPListener()); 
B[1].setOnTouchListener(new MPListener()); 

Ничего не изменилось. Я могу по-прежнему нажимать обе кнопки самостоятельно, но не в одно и то же время.

EDIT: Таким образом, я сделал новую новую деятельность на случай, если что-то еще проблема.Вот полный код моего нового вида деятельности в:

package com.example.projectname; 

import android.os.Bundle; 
import android.app.Activity; 
import android.content.Context; 
import android.graphics.drawable.Drawable; 
import android.view.MotionEvent; 
import android.view.View; 
import android.view.Window; 
import android.view.WindowManager; 
import android.view.View.OnTouchListener; 
import android.widget.ImageView; 

public class About extends Activity 
{ 

    private class MPListener implements OnTouchListener 
    { 
     @Override 
     public boolean onTouch(View v, MotionEvent event) { 
      if(event.getAction() == MotionEvent.ACTION_UP) 
      { 
       if(v.getId()==B[0].getId()) 
        B[0].setImageDrawable(Bok[0]); 
       if(v.getId()==B[1].getId()) 
        B[1].setImageDrawable(Bok[1]); 
      } 
      else if(event.getAction() == MotionEvent.ACTION_DOWN) 
      { 
       if(v.getId()==B[0].getId()) 
        B[0].setImageDrawable(Bpressed[0]); 
       if(v.getId()==B[1].getId()) 
        B[1].setImageDrawable(Bpressed[1]); 
      } 
      return true; 
     } 
    } 

    ImageView[] B; 
    Drawable[] Bok,Bpressed; 
    @Override 
    protected void onCreate(Bundle savedInstanceState) 
    { 
     //standard oncreate stuff 
     super.onCreate(savedInstanceState); 
     requestWindowFeature(Window.FEATURE_NO_TITLE); 
     getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN); 
     setContentView(R.layout.activity_about); 

     Context context=getApplicationContext(); 

     B=new ImageView[2]; 
     Bok=new Drawable[2]; 
     Bpressed=new Drawable[2]; 

     Bok[0] = context.getResources().getDrawable(R.drawable.bblue); 
     Bok[1] = context.getResources().getDrawable(R.drawable.bpurp); 
     Bpressed[0] = context.getResources().getDrawable(R.drawable.bpressedblue); 
     Bpressed[1] = context.getResources().getDrawable(R.drawable.bpressedpurp); 

     B[0] = (ImageView) findViewById(R.id.imageView1); 
     B[1] = (ImageView) findViewById(R.id.imageView2); 
     B[0].setImageDrawable(Bok[0]); 
     B[1].setImageDrawable(Bok[1]); 

     B[0].setOnTouchListener(new MPListener()); 
     B[1].setOnTouchListener(new MPListener()); 
    } 
} 

Все то же самое, как всегда. Как только я нажимаю одну кнопку, другой становится невосприимчивым.

+0

Очевидно, что если вы коснулись B [0] первый (и не отпускали), а затем нажмите B [1], это означает, что B [1] получит событие ACTION_POINTER_DOWN, потому что для второго касания. Вы должны добавить проверку для 'ACTION_POINTER_DOWN' для B [1] так же, как для B [0]. – Stan

+0

@Stan О, это просто опечатка. Я все еще не работаю, когда исправляю это. Кроме того, это не работает наоборот (B [1] -> B [0]) – RandomUsername

+0

Вы должны проверить действие после применения маски: 'if (event.getAction() & MotionEvent.ACTION_MASK == ...) '. – Stan

ответ

1

Android может выбрать для вас, что было нажато в каком порядке, и если он по-прежнему тронут или нет. Просто дайте две кнопки разных слушателей. Что-то вроде этого кода:

@Override 
protected void onCreate(Bundle savedInstanceState) { 
    Log.d("TEST", "Begin onCreate"); 
    super.onCreate(savedInstanceState); 
    Log.d("TEST", "End onCreate"); 

    setContentView(R.layout.test); 
    findViewById(R.id.upperTouchable).setOnTouchListener(new MyTouchListener()); 
    findViewById(R.id.lowerTouchable).setOnTouchListener(new MyTouchListener()); 
} 

private boolean lowerIsTouched = false; 
private boolean upperIsTouched = false; 

private void setInfo() { 
    if(lowerIsTouched && upperIsTouched) 
     ((TextView) findViewById(R.id.info)).setText("both touched"); 
    else if(lowerIsTouched) 
     ((TextView) findViewById(R.id.info)).setText("only lower is touched"); 
    else if(upperIsTouched) 
     ((TextView) findViewById(R.id.info)).setText("only upper is touched"); 
    else 
     ((TextView) findViewById(R.id.info)).setText("non is touched"); 

    ((TextView) findViewById(R.id.lowerTouchable)).setText(lowerIsTouched? "touched":"not touched"); 
    ((TextView) findViewById(R.id.upperTouchable)).setText(upperIsTouched? "touched":"not touched"); 
} 

private class MyTouchListener implements OnTouchListener { 
    @Override 
    public boolean onTouch(View v, MotionEvent event) { 
     if(event.getAction() == MotionEvent.ACTION_DOWN) { 
      if(v.getId() == R.id.lowerTouchable) 
       lowerIsTouched = true; 
      else if(v.getId() == R.id.upperTouchable) 
       upperIsTouched = true; 
      setInfo(); 
     } 
     else if(event.getAction() == MotionEvent.ACTION_UP) { 
      if(v.getId() == R.id.lowerTouchable) 
       lowerIsTouched = false; 
      else if(v.getId() == R.id.upperTouchable) 
       upperIsTouched = false; 
      setInfo(); 
     } 
     return true; 
    } 
} 

и соответствующая раскладка:

<?xml version="1.0" encoding="utf-8"?> 
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
android:layout_width="match_parent" 
android:layout_height="match_parent" 
android:orientation="vertical" > 

<TextView 
    android:id="@+id/info" 
    android:layout_width="fill_parent" 
    android:layout_height="wrap_content" 
    android:gravity="center" 
    android:background="#FFFFFFFF" 
android:text="Non touched" 
    android:textAppearance="?android:attr/textAppearanceLarge" /> 

<TextView 
    android:id="@+id/upperTouchable" 
    android:layout_width="fill_parent" 
    android:layout_height="0dp" 
    android:layout_weight="1" 
    android:gravity="center" 
    android:text="Not touched" 
    android:background="#FFF0F0F0" 
    android:textAppearance="?android:attr/textAppearanceLarge" /> 

<TextView 
    android:id="@+id/lowerTouchable" 
    android:layout_width="fill_parent" 
    android:layout_height="0dp" 
    android:layout_weight="1" 
    android:gravity="center" 
    android:text="Not touched" 
    android:background="#FFFFFFFF" 
    android:textAppearance="?android:attr/textAppearanceLarge" /> 

</LinearLayout> 
+0

Я попробую сейчас, спасибо. – RandomUsername

+0

Я сделал редактирование, проверьте его. Я попробую изменить ваш код, чтобы увидеть, может ли он работать. Я добавил ACTION_POINTER_UP части кода, и ваш подход, похоже, ничего не меняет. Это то же самое, что когда я реализовал прослушиватель непосредственно в своем классе. – RandomUsername

+1

Если увидишь свое редактирование. Я думаю, что я до сих пор не понимаю полностью, какое точное поведение вы ищете. Позвольте мне объяснить мои слова: кнопка может иметь три состояния: «неровные», «нажатые», «невосприимчивые». На экране есть две кнопки. Первоначально обе кнопки находятся в состоянии «не нажаты». Если нажата одна кнопка, тогда она переходит в состояние «нажата», а другая кнопка в состояние «не отвечает». Если другая кнопка теперь коснулась, она не реагирует. Если первая кнопка отпущена, обе кнопки превращаются в stae «unpressed». Все в порядке? Если, так что я могу изменить свой код, чтобы это сделать. Просто дай мне знать. – jboi

Смежные вопросы