JavascriptProva

venerdì 15 aprile 2016

Multitouch: ricominciando da zero.

Ancora sul "two fingers": voglio penetrare un po' più a fondo in questa singolare caratteristica della programmazione per cellulari, che ovviamente con il mouse non è ripetibile, almeno penso...

Aggrediamo la cosa!
Intanto mi predispongo un'Activity con un'immagine presa dalle risorse direttamente nel codice xml.
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context="com.example.idea.MainActivity" >

    <ImageView
        android:id="@+id/imageView1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerHorizontal="true"
        android:layout_centerVertical="true"
        android:src="@drawable/lucchiuso" />

</RelativeLayout> 


Quindi la attribuisco a una variabile nel codice Java, e le attribuisco un listener...

Ecco l'immagine istanziata nel codice Java:
public class MainActivity extends Activity {
 
 ImageView imageView;
 
 @Override
 protected void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.activity_main);
  
  imageView=(ImageView)findViewById(R.id.imageView1);
  
 }

}
Creo ora il listener.
public class MainActivity extends Activity {
 
 ImageView imageView;
 
 @Override
 protected void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.activity_main);
  
  imageView=(ImageView)findViewById(R.id.imageView1);
  
  OnTouchListener onTouchListener=new View.OnTouchListener() {
   
   @Override
   public boolean onTouch(View v, MotionEvent event) {
    if(event.getAction()==MotionEvent.ACTION_DOWN){
     Log.d("PUNTATORE", "PRINCIPALE");
    }
    return false;
   }
  };
  
  imageView.setOnTouchListener(onTouchListener);
 }

}
che, nelle mie intenzioni dovrebbe dare, in LogCat, "PUNTATORE" "PRINCIPALE", che in effetti, verificato, risulta dare ogni volta che clicco sull'immagine:
04-15 01:04:36.059: D/PUNTATORE(3990): PRINCIPALE
04-15 01:04:37.227: D/PUNTATORE(3990): PRINCIPALE
04-15 01:04:38.193: D/PUNTATORE(3990): PRINCIPALE

Ma ora, in vista dei puntatori aggiuntivi, è bene che provi la cosa sul cellulare.
04-15 11:52:45.011: D/PUNTATORE(21255): PRINCIPALE

Anche qui funziona come previsto.
Ora, tenendo conto che esiste anche un MotionEvent per puntatori aggiuntivi, provo a usarlo...
  OnTouchListener onTouchListener=new View.OnTouchListener() {
   
   @Override
   public boolean onTouch(View v, MotionEvent event) {
    if(event.getAction()==MotionEvent.ACTION_DOWN){
     Log.v("PUNTATORE", "PRINCIPALE");
    }
    if(event.getAction()==MotionEvent.ACTION_POINTER_DOWN){
     Log.v("PUNTATORE","AGGIUNTIVO");
    }
    return true;
   }
  };
e non funziona, ossia mi dà solo il riscontro del puntatore principale. (Ho cambiato in Log.v per giocare un po' sulle visualizzazioni di LogCat, senza un motivo rilevante).

Ottengo, provando più volte, anche la visualizzazione del puntatore aggiuntivo, ma in un modo molto caotico in cui non riesco a individuare la regola...

Dopo un po' di "impazzimenti" vari, ho deciso di copiare pedissequamente un codice da un tutorial, basato su onTouchEvent e non su onTouch, e funziona come previsto.
Lo riscrivo di sana pianta, un po' trasformato a modo mio, per possederlo.

Riparto dall'inizio:
public class MainActivity extends Activity {
 
 ImageView imageView;
 
 @Override
 protected void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.activity_main);
  
  imageView=(ImageView)findViewById(R.id.imageView1);
 
 }
 
}
E vado:
public class MainActivity extends Activity {
 
 ImageView imageView;
 
 @Override
 protected void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.activity_main);
  
  imageView=(ImageView)findViewById(R.id.imageView1);
 
 }
 
 @Override
 public boolean onTouchEvent(MotionEvent event){
  
  switch (event.getAction()){
  case MotionEvent.ACTION_DOWN:
   Log.v("TOCCO","Primo dito giù");
   break;
  
  case MotionEvent.ACTION_POINTER_DOWN:
   Log.v("TOCCO","Secondo dito giù");
   break;
  }
  
  return true;
  
 }
 
}
E ora vediamo se funziona...

No! Non funziona!
Individua soltanto il tocco del primo dito!

Ma indagando sul codice originale che ho copiato prima, noto che (non me ne ero accorto facendo il pedissequo copia-incolla) esso usa MotionEvent.ACTION_MASK, che non ho assolutamente idea di cosa significhi: deve essere qui il problema...
Indaghiamo su questo misterioso ACTION_MASK...

Ho idea che c'entri il calcolo binario, a giudicare dall'operatore &.

...che infatti è l'operatore logico AND!
Vediamo ora i codici numerici delle varie MotionEvent...

I valori numerici delle costanti MotionEvent sono:
  • ACTION_DOWN 0x00000000
  • ACTION_POINTER_DOWN 0x00000005.
  • ACTION_MASK 0x000000ff
Non capisco però a che scopo mascherare in questo modo una costante che ha tutti zeri tranne l'ultimo byte.

Non voglio addentrarmi troppo, per ora: scrivo meglio il codice:
public class MainActivity extends Activity {
 
 ImageView imageView;
 
 @Override
 protected void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.activity_main);
  
  imageView=(ImageView)findViewById(R.id.imageView1);
 
 }
 
 @Override
 public boolean onTouchEvent(MotionEvent event){
  int azione=event.getAction() & MotionEvent.ACTION_MASK;
  switch (azione){
  case MotionEvent.ACTION_DOWN:
   Log.v("TOCCO","Primo dito giù");
   break;
  
  case MotionEvent.ACTION_POINTER_DOWN:
   Log.v("TOCCO","Secondo dito giù");
   break;
  }
  
  return true;
  
 }
 
}
Ora funziona!

Nessun commento:

Posta un commento