2011-01-17 16 views
6

Come sviluppatore, tendo a programmare prima, poi a cercare in seguito. Stavo cercando di implementare uno schermo che gestisse più input utente. Fondamentalmente mappare più di un dito. Ho provato due cose ..Multitouch Android?

Avevo una classe di attività che implementava OnTouchListener. Qui ho avuto due viste secondarie separate che hanno aggiunto l'attività come ascoltatori onuch. E poi ho avuto una linea di stampa che ha stampato l'evento.getPointerCount() e stampato la posizione di ciascuno dei puntatori ..

Scaricato sul telefono e testato. Ho notato che i puntatori non sono mai cresciuti più di due. Ho anche notato che se un dito era su un bambino e un altro sull'altro bambino, gli eventi erano solo al primo componente figlio. Successivamente ho provato a mettere ascoltatori separati su ciascuno dei componenti figlio per vedere se avrebbe funzionato, ma avrebbe funzionato allo stesso modo.

Quindi, sembra che Android supporti solo un totale di due input utente quando si tratta di input da parte dell'utente che tocca lo schermo.

È vero? Sembra da test e ricerca che questo è il caso.

Qualcuno si è imbattuto in questa limitazione. Qualche lavoro intelligente intorno?

Grazie per il tuo tempo e le risposte.

dk

risposta

7

Il numero di punti di contatto supportati dipende dal dispositivo. In tutte le versioni attualmente disponibili di Android MotionEvent vengono inviati a una singola vista di destinazione e vengono descritti lo stato di tutti i punti di contatto attualmente attivi. La vista di destinazione è determinata da dove si verifica il primo evento MotionEvent.ACTION_DOWN.

Vedere il post Making Sense of Multitouch sul blog degli sviluppatori Android per una rapida panoramica del lavoro con gli eventi multitouch su Android.

+0

Grazie per l'URL, ha aiutato cancellare alcune cose. Ma dovevo vederlo per me stesso. Così, ho scritto una semplice app per testare ciò che è stato detto nell'articolo. Aggiungerà il codice per rispondere autonomamente a questa domanda. – dakira

3

Ho scritto un'applicazione molto semplice per testare più touch sul mio telefono HTC Incredible. Mi comporto più o meno come pensavo e più o meno come l'URL fornito da adamp. Il mio risultato è che il telefono poteva gestire solo due input. Ho per scatola che ognuno ha il proprio OnTouchListener. Quando clicco su ciascuna casella, stampo un testo per ciascuno. Facendo clic su ogni evento di tocco, ma con il mio indice ho fatto clic su un punto qualsiasi dello schermo, ho ottenuto due indicatori. Dal metodo eventEget.getPointerCount di MotionEvent. Non importava dove fosse atterrato il secondo dito. Potrebbe essere stato al di fuori della vista originale che ha ricevuto il primo dito verso il basso. Comunque qui è il codice se ti piace provarlo da solo.

Ho un 7z dell'intero progetto ma non penso di poterlo allegare.

Quindi, ecco l'attività principale e l'xml per il layout.

package com.multitouch; 

import android.app.Activity; 
import android.os.Bundle; 
import android.os.Handler; 
import android.util.Log; 
import android.view.MotionEvent; 
import android.view.View; 
import android.view.View.OnTouchListener; 
import android.widget.LinearLayout; 
import android.widget.TextView; 

public class MultiTouch extends Activity { 
    protected LinearLayout sq1; 
    protected LinearLayout sq2; 
    protected LinearLayout sq3; 
    protected LinearLayout sq4; 

    protected String sqText = new String(); 
    protected String sq1Text = new String(); 
    protected String sq2Text = new String(); 
    protected String sq3Text = new String(); 

    private Handler handler = new Handler(); 

    /** Called when the activity is first created. */ 
    @Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.main); 
     setViews(); 
     handler.postDelayed(mUpdateUITimerTask, 5000); 
    } 

    private final Runnable mUpdateUITimerTask = new Runnable() { 
     public void run() { 
      // do whatever you want to change here, like: 
      updateTextField(); 
     } 
    }; 

    private void updateTextField() { 
     TextView view1 = (TextView) this.findViewById(R.id.logView); 
     TextView view2 = (TextView) this.findViewById(R.id.logView1); 
     TextView view3 = (TextView) this.findViewById(R.id.logView2); 
     TextView view4 = (TextView) this.findViewById(R.id.logView3); 


     //view1.append(sqText + "\n"); 
     view1.setText(sqText); 
     view2.setText(sq1Text); 
     view3.setText(sq2Text); 
     view4.setText(sq3Text); 

     handler.post(mUpdateUITimerTask); 
    } 

    private void setViews() { 
     sq1 = (LinearLayout) this.findViewById(R.id.square1); 
     sq2 = (LinearLayout) this.findViewById(R.id.square2); 
     sq3 = (LinearLayout) this.findViewById(R.id.square3); 
     sq4 = (LinearLayout) this.findViewById(R.id.square4); 

     sq1.setOnTouchListener(new TouchListener()); 
     sq2.setOnTouchListener(new TouchListener()); 
     sq3.setOnTouchListener(new TouchListener()); 
     sq4.setOnTouchListener(new TouchListener());   
    } 

    private class TouchListener implements OnTouchListener { 

     @Override 
     public boolean onTouch(View v, MotionEvent event) { 

      if(event.getPointerCount()>2) { 
       sq1Text = "GOT THREE POINTERS!!"; 
       sq2Text = "GOT THREE POINTERS!!"; 
       sq3Text = "GOT THREE POINTERS!!"; 
       sqText = "GOT THREE POINTERS!!"; 
      } 

      if(event.getAction() == MotionEvent.ACTION_DOWN){ 
       switch(v.getId()) { 
        case R.id.square1: 
         sqText = "Square 1 Pressed::Pointer count = " + String.valueOf(event.getPointerCount()); 
        break; 
        case R.id.square2: 
         sq1Text = "Square 2 Pressed::Pointer count = " + String.valueOf(event.getPointerCount()); 
        break; 
        case R.id.square3: 
         sq2Text = "Square 3 Pressed::Pointer count = " + String.valueOf(event.getPointerCount()); 
        break; 
        case R.id.square4: 
         sq3Text = "Square 4 Pressed::Pointer count = " + String.valueOf(event.getPointerCount()); 
        break; 
       } 
      } else if(event.getAction() == MotionEvent.ACTION_POINTER_DOWN || 
         event.getAction() == MotionEvent.ACTION_POINTER_UP) { 
       switch(v.getId()) { 
        case R.id.square1: 
         sqText = "Square 1 Pointer Down::Pointer count = " + String.valueOf(event.getPointerCount()) + "\n"; 
        break; 
        case R.id.square2: 
         sq1Text = "Square 2 Pointer Down::Pointer count = " + String.valueOf(event.getPointerCount()) + "\n"; 
        break; 
        case R.id.square3: 
         sq2Text = "Square 3 Pointer Down::Pointer count = " + String.valueOf(event.getPointerCount()) + "\n"; 
        break; 
        case R.id.square4: 
         sq3Text = "Square 4 Pointer Down::Pointer count = " + String.valueOf(event.getPointerCount()) + "\n"; 
        break; 
       } 
      } else if(event.getAction() == MotionEvent.ACTION_POINTER_1_DOWN) { 
       switch(v.getId()) { 
        case R.id.square1: 
         sqText = "Square 1 Pointer1Down::Pointer count = " + String.valueOf(event.getPointerCount()) + "\n"; 
        break; 
        case R.id.square2: 
         sq1Text = "Square 2 Pointer1Down::Pointer count = " + String.valueOf(event.getPointerCount()) + "\n"; 
        break; 
        case R.id.square3: 
         sq2Text = "Square 3 Pointer1Down::Pointer count = " + String.valueOf(event.getPointerCount()) + "\n"; 
        break; 
        case R.id.square4: 
         sq3Text = "Square 4 Pointer1Down::Pointer count = " + String.valueOf(event.getPointerCount()) + "\n"; 
        break; 
       } 
      } else if(event.getAction() == MotionEvent.ACTION_POINTER_2_DOWN) { 
       switch(v.getId()) { 
        case R.id.square1: 
         sqText = "Square 1 Pointer2Down::Pointer count = " + String.valueOf(event.getPointerCount()) + "\n"; 
        break; 
        case R.id.square2: 
         sq1Text = "Square 2 Pointer2Down::Pointer count = " + String.valueOf(event.getPointerCount()) + "\n"; 
        break; 
        case R.id.square3: 
         sq2Text = "Square 3 Pointer2Down::Pointer count = " + String.valueOf(event.getPointerCount()) + "\n"; 
        break; 
        case R.id.square4: 
         sq3Text = "Square 4 Pointer2Down::Pointer count = " + String.valueOf(event.getPointerCount()) + "\n"; 
        break; 
       } 
      } else if(event.getAction() == MotionEvent.ACTION_POINTER_3_DOWN) { 
       switch(v.getId()) { 
        case R.id.square1: 
         sqText = "Square 1 Pointer3Down::Pointer count = " + String.valueOf(event.getPointerCount()) + "\n"; 
        break; 
        case R.id.square2: 
         sq1Text = "Square 2 Pointer3Down::Pointer count = " + String.valueOf(event.getPointerCount()) + "\n"; 
        break; 
        case R.id.square3: 
         sq2Text = "Square 3 Pointer3Down::Pointer count = " + String.valueOf(event.getPointerCount()) + "\n"; 
        break; 
        case R.id.square4: 
         sq3Text = "Square 4 Pointer3Down::Pointer count = " + String.valueOf(event.getPointerCount()) + "\n"; 
        break; 
       } 
      } else if(event.getAction() == MotionEvent.ACTION_UP) { 
       switch(v.getId()) { 
        case R.id.square1: 
         sqText = "Square 1 UP::Pointer count = " + String.valueOf(event.getPointerCount()) + "\n"; 
        break; 
        case R.id.square2: 
         sq1Text = "Square 2 UP::Pointer count = " + String.valueOf(event.getPointerCount()) + "\n"; 
        break; 
        case R.id.square3: 
         sq2Text = "Square 3 UP::Pointer count = " + String.valueOf(event.getPointerCount()) + "\n"; 
        break; 
        case R.id.square4: 
         sq3Text = "Square 4 UP::Pointer count = " + String.valueOf(event.getPointerCount()) + "\n"; 
        break; 
       } 
      } else if(event.getAction() == MotionEvent.ACTION_MOVE) { 
       switch(v.getId()) { 
        case R.id.square1: 
         sqText = "Square 1 MOVE::Pointer count = " + String.valueOf(event.getPointerCount()) + "\n"; 
        break; 
        case R.id.square2: 
         sq1Text = "Square 2 MOVE::Pointer count = " + String.valueOf(event.getPointerCount()) + "\n"; 
        break; 
        case R.id.square3: 
         sq2Text = "Square 3 MOVE::Pointer count = " + String.valueOf(event.getPointerCount()) + "\n"; 
        break; 
        case R.id.square4: 
         sq3Text = "Square 4 MOVE::Pointer count = " + String.valueOf(event.getPointerCount()) + "\n"; 
        break; 
       } 
      } 


      // TODO Auto-generated method stub 
      return true; 
     } 

    } 
} 

Disposizione:

<?xml version="1.0" encoding="utf-8"?> 
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    android:orientation="vertical" 
    android:gravity="center_horizontal" 
    android:layout_width="fill_parent" 
    android:layout_height="fill_parent" 
    android:id="@+id/MainLay" > 

    <TableLayout xmlns:android="http://schemas.android.com/apk/res/android" 
     android:layout_width="fill_parent" 
     android:layout_height="fill_parent" 
     android:orientation="vertical" 
     android:gravity="center_horizontal" android:padding="10dip"> 


     <TableRow android:gravity="center_horizontal" android:padding="10dip"> 
      <LinearLayout android:background="#FFFF00" android:id="@+id/square1" android:padding="10px" android:layout_width="125px" android:layout_height="125px"/> 
      <LinearLayout android:background="#FF00FF" android:id="@+id/square2" android:padding="10px" android:layout_width="125px" android:layout_height="125px"/> 
     </TableRow> 

     <TableRow android:gravity="center_horizontal" android:padding="10dip"> 
      <LinearLayout android:background="#00FFFF" android:id="@+id/square3" android:padding="10px" android:layout_width="125px" android:layout_height="125px"/> 
      <LinearLayout android:background="#eeeeee" android:id="@+id/square4" android:padding="10px" android:layout_width="125px" android:layout_height="125px"/> 
     </TableRow>  


      <TextView android:id="@+id/logView" android:layout_width="wrap_content" android:layout_height="wrap_content"/> 
      <TextView android:id="@+id/logView1" android:layout_width="wrap_content" android:layout_height="wrap_content"/> 
      <TextView android:id="@+id/logView2" android:layout_width="wrap_content" android:layout_height="wrap_content"/> 
      <TextView android:id="@+id/logView3" android:layout_width="wrap_content" android:layout_height="wrap_content"/> 



    </TableLayout> 

</LinearLayout> 

Buona fortuna, e se lo provate fatemi sapere se si ottiene il GOT tre punti !! stampare dichiarazioni. Mi chiedo che cosa supporti i telefoni.

grazie, dk

+0

Galaxy S sembra supportare fino a cinque contatori. Dimostrato da qualcuno da un forum diverso utilizzando il software sopra. – dakira

+0

Utilizzo di un LG Optimus. Rileva solo 1 contatore. – Brahadeesh

0

Ho modificato @dakira risposta.Ecco il codice di mio campione:

<?xml version="1.0" encoding="utf-8"?> 
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    android:id="@+id/MainLay" 
    android:layout_width="fill_parent" 
    android:layout_height="fill_parent" 
    android:gravity="center_horizontal" 
    android:orientation="vertical"> 


    <RelativeLayout 
     android:layout_width="match_parent" 
     android:layout_height="wrap_content"> 

     <TextView 
      android:id="@+id/tvHeader" 
      android:layout_width="match_parent" 
      android:layout_height="wrap_content" 
      android:gravity="center" 
      android:padding="4dp" 
      android:text="Place Your Finger on Squire" 
      android:textColor="#000" 
      android:textSize="20sp" /> 

     <LinearLayout 
      android:id="@+id/llStatusHolder" 
      android:layout_width="match_parent" 
      android:layout_height="wrap_content" 
      android:layout_below="@+id/tvHeader" 
      android:orientation="vertical" 
      android:weightSum="2"> 

      <LinearLayout 
       android:layout_width="match_parent" 
       android:layout_height="wrap_content" 
       android:orientation="horizontal" 
       android:padding="8dp" 
       android:weightSum="2"> 

       <TextView 
        android:id="@+id/tvBox1" 
        android:layout_width="match_parent" 
        android:layout_height="wrap_content" 
        android:layout_weight="1" 
        android:background="#FFFF00" 
        android:gravity="center" 
        android:padding="4dp" 
        android:text="Finger : 0" 
        android:textColor="#000" 
        android:textSize="28sp" /> 

      </LinearLayout> 

     </LinearLayout> 


     <LinearLayout 
      android:id="@+id/square1" 
      android:layout_width="match_parent" 
      android:layout_height="match_parent" 
      android:layout_margin="4dp" 
      android:layout_below="@+id/llStatusHolder" 
      android:layout_weight="1" 
      android:background="#FFFF00" 
      android:orientation="horizontal" 
      android:padding="10dp"> 

     </LinearLayout> 

     </RelativeLayout> 
    </LinearLayout> 

Qui è il codice Java:

import android.app.Activity; 
import android.os.Bundle; 
import android.view.MotionEvent; 
import android.view.View; 
import android.view.View.OnTouchListener; 
import android.widget.LinearLayout; 
import android.widget.TextView; 


public class MultiTouchTestActivity extends Activity { 
    protected LinearLayout sq1; 

    TextView tvBox1; 
    int counter1 = 0; 

    @Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_multi_touch_test); 
     setViews(); 
    } 

    private void updateTextField() { 

     tvBox1.setText("Finger : " + counter1); 

    } 

    private void setViews() { 
     tvBox1 = (TextView) findViewById(R.id.tvBox1); 
     sq1 = (LinearLayout) this.findViewById(R.id.square1); 

     sq1.setOnTouchListener(new TouchListener()); 

    } 

    private class TouchListener implements OnTouchListener { 

     @Override 
     public boolean onTouch(View v, MotionEvent event) { 

      if (event.getAction() == 1) { 
       setCounterValue(1, 0); 
      }else if (event.getAction() == MotionEvent.ACTION_DOWN) { 
       setCounterValue(1, event.getPointerCount()); 
      } else if (event.getAction() == MotionEvent.ACTION_POINTER_DOWN || 
        event.getAction() == MotionEvent.ACTION_POINTER_UP) { 
       setCounterValue(1, event.getPointerCount()); 
      } else if (event.getAction() == MotionEvent.ACTION_POINTER_1_DOWN) { 
       setCounterValue(1, event.getPointerCount()); 
      } else if (event.getAction() == MotionEvent.ACTION_POINTER_2_DOWN) { 
       setCounterValue(1, event.getPointerCount()); 
      } else if (event.getAction() == MotionEvent.ACTION_POINTER_3_DOWN) { 
       setCounterValue(1, event.getPointerCount()); 
      } else if (event.getAction() == MotionEvent.ACTION_UP) { 
       setCounterValue(1, event.getPointerCount()); 
      } else if (event.getAction() == MotionEvent.ACTION_MOVE) { 
       setCounterValue(1, event.getPointerCount()); 
      }else if (event.getAction() == MotionEvent.ACTION_BUTTON_RELEASE) { 
       setCounterValue(1, 0); 
      } 
      updateTextField(); 
      return true; 
     } 
    } 

    void setCounterValue(int hasvalue, int value) { 
     switch (hasvalue) { 
      case 1: 
       counter1 = value; 
       break; 
     } 
    } 
} 

Spero che questo risolverà molti persone problema :)

enter image description here

Problemi correlati