2013-07-25 13 views
6

Sto provando a vedere se esiste un modo per creare un singolo metodo per implementare un listener di tocco per più pulsanti, visto che ho un paio di pulsanti che fanno quasi esattamente il stessa cosa. L'unica differenza in ciò che fanno è il messaggio che invierebbe tramite il mio metodo sendMessage(), e per quanto tempo il pulsante deve essere tenuto premuto per il messaggio da inviare. Se c'è un modo per farlo, quale potrebbe essere? E inoltre, perché non dovrebbe funzionare qualcosa del genere?Unico metodo per implementare onTouchListener() per più pulsanti

//Within onCreate Method... 
Button mButton = (Button) findViewbyId(R.id.three_sec_button); 
mButton = addTouchTimer(mButton, 3, 3); 

chiede -

private Button addTouchTimer(Button button, final int sec, final int messageNum){ 
     button.setOnTouchListener(new View.OnTouchListener() { 
      boolean longEnough = false; 
      long realTimeLeft = sec * 1000; 
      @Override 
      // This will make it so that a message is only sent if the button is held down for 3 seconds 
      // Otherwise it won't send. It is sent during the hold down process, releasing it returns a false 
      // value and no message is sent. 
      public boolean onTouch(View arg0, MotionEvent arg1) { 
       Log.d("Button", "Touchy Touchy!"); 
       if(arg1.getAction() == MotionEvent.ACTION_DOWN){ 
        buttonPressTime = new CountDownTimer(realTimeLeft, 1000){ 
         @Override 
         public void onTick(long millisUntilDone){ 
           realTimeLeft = millisUntilDone; 
         } 

         @Override 
         public void onFinish() { 
          long timeLeft = realTimeLeft; 
          long currTime = System.currentTimeMillis(); 
          long realFinishTime = currTime + timeLeft; 
           while(currTime < realFinishTime){ 
            currTime = System.currentTimeMillis(); 
           } 
          longEnough = true; 
          sendEmergencyMessage(longEnough, messageNum); 
         } 
        }.start(); 
       } 
       else if(arg1.getAction() == MotionEvent.ACTION_UP){ 
        buttonPressTime.cancel(); 
        sendMessage(longEnough, messageNum); 
       } 
       return longEnough; 
      }   
     }); 

     return button; 
    } 

E sembra proprio che, per l'amor di efficienza ci deve essere un modo migliore di farlo che attuare i singoli ascoltatori per ogni pulsante. Come nota, sendMessage() ha una chiamata di registro che utilizza il valore booleano, voglio vedere come viene impostato quando viene passato. Questo è l'unico motivo per cui viene chiamato durante il rilascio del pulsante.

risposta

17

Sì, hai ragione, c'è un modo migliore. Un singolo TouchListener che gestisce tutto, determinando il pulsante tramite l'id.

void intialization(){ 
    Button m1, m2, m3, m4; 
    ... //do initialization stuff 
    m1.setId(1); 
    m2.setId(2); 
    m3.setId(3); 
    m4.setId(4); 
    MyTouchListener touchListener = new MyTouchListener(); 
    m1.setOnTouchListener(touchListener); 
    m2.setOnTouchListener(touchListener); 
    m3.setOnTouchListener(touchListener); 
    m4.setOnTouchListener(touchListener); 
} 

public class MyTouchListener implements OnTouchListener { 
    @Override 
    public boolean onTouch(View v, MotionEvent event) { 
     switch(v.getId()){ 
      case 1: 
       //do stuff for button 1 
       break; 
      case 2: 
       //do stuff for button 2 
       break; 
      case 3: 
       //do stuff for button 3 
       break; 
      case 4: 
       //do stuff for button 4 
       break; 
     } 
     return true; 
    } 

} 

Ed è così che lo faresti! Un approccio numerico per gli id ​​è molto utile in questo caso. Un altro approccio è quello di fare in modo che la tua attività implementa OnTouchListener nella tua attività, e quindi il tuo codice sarebbe ancora più semplice.

public class MyActivity extends Activity implements OnTouchListener { 

    void initialization(){ 
     Button m1, m2, m3, m4; 
     ... //do initialization stuff 
     m1.setId(1); 
     m2.setId(2); 
     m3.setId(3); 
     m4.setId(4); 
     m1.setOnTouchListener(this); 
     m2.setOnTouchListener(this); 
     m3.setOnTouchListener(this); 
     m4.setOnTouchListener(this); 
    } 

    @Override 
    public boolean onTouch(View v, MotionEvent event) { 
     switch(v.getId()){ 
      case 1: 
       //do stuff for button 1 
       break; 
      case 2: 
       //do stuff for button 2 
       break; 
      case 3: 
       //do stuff for button 3 
       break; 
      case 4: 
       //do stuff for button 4 
       break; 
     } 
     return true; 
    } 

} 

Nota: Questo approccio anche funzionerà anche per OnClickListener, OnCheckedChangeListener, o qualsiasi altro ascoltatore che si dovrebbe impostare su una visione Android.

+0

uomo, mi potrebbe essere stato seduti dal computer troppo a lungo. Avrei dovuto sapere questo.Tuttavia, domanda. Vuoi dire che dovrei implementare una nuova classe chiamata MyTouchListener o l'hai appena aggiunta arbitrariamente? Non posso semplicemente fare ciò che è stato detto di seguito e implementarlo nella mia classe principale e quindi chiamare il metodo onTouch come "m1.setOnTouchListener (onTouch()); – zgc7009

+0

Puoi rendere la tua attività principale implementare l'ascoltatore del tocco e vedere la mia risposta per riferimento – Chetna

+0

@ zgc7009: Se abbiamo risolto il tuo problema, ti preghiamo di accettarne uno come risposta.Può essere utile per gli altri – Chetna

4

Sì, c'è un approccio migliore per fare lo stesso.
1) Realizza la tua classe OnTouchListener.
2) Aggiungi questo listener a ogni pulsante che dovrebbe gestire l'evento di tocco. Come questo:

button1.setOnTouchListener(this); 

3) E in questo metodo public boolean onTouch(View arg0, MotionEvent arg1) {});

è possibile utilizzare caso interruttore sulla considerazione che è stato toccato. Il primo argomento, ad esempio arg0, è la vista in cui è stato inviato l'evento tattile. Nel tuo caso saranno pulsanti diversi. Qualcosa di simile a questo:

public boolean onTouch(View arg0, MotionEvent arg1) { 
    if (arg1.getAction() == MotionEvent.ACTION_DOWN) { 
     switch (arg0.getId()) { 
     case R.id.button1: // Id of the button 
      // Your code goes here 
      break; 

     case R.id.button2: // Id of the button 
      // Your code goes here 
      break; 

     default: 
      break; 
     } 
    } 
    return true; 
} 
+1

Funziona anche, ho mescolato e abbinato il tuo con la risposta di cui sopra, in particolare utilizzando setId() getId(). La sua era un po 'prima quindi gli ho dato l'assegno, ma anche questo funziona bene. Se potessi, ti darei entrambi i controlli di approvazione. – zgc7009

+0

Questo è completamente soddisfacente :) – Chetna

1
OnTouchListener mOnTouchListener = new OnTouchListener() { 

    @Override 
    public boolean onTouch(View v, MotionEvent event) { 
     // Code goes here 
    return true; 
    } 
}; 

button1.setOnTouchListener(mOnTouchListener); 
button2.setOnTouchListener(mOnTouchListener); 
1

ho unire due risposta, questo è il mio codice

public class MyActivity extends Activity implements OnTouchListener { 
Button mGreen, mRed; 

void initialization() { 

    ... //do initialization stuff 

    mGreen.setOnTouchListener(this); 
    mRed.setOnTouchListener(this); 
} 

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


    switch (event.getAction() & MotionEvent.ACTION_MASK) { 
     case MotionEvent.ACTION_DOWN: 
      actionDown(); 
      break; 
     case MotionEvent.ACTION_UP: 
      actionUp(); 
      break; 

     case MotionEvent.ACTION_POINTER_DOWN: 
      break; 

     case MotionEvent.ACTION_POINTER_UP: 
      break; 

     case MotionEvent.ACTION_MOVE: 
      actionMove(); 
      break; 
    } 

    return true; 
} 

public void actionDown() { 
    switch (view.getId()) { 
     case R.id.button_green: 
      //todo 
      break; 

     case R.id.button_red: 
      //todo 
      break; 
    } 
} 

public void actionUp() { 
    switch (view.getId()) { 
     case R.id.button_green: 
      //todo 
      break; 


     case R.id.button_red: 
      //todo 
      break; 
    } 
} 

public void actionMove() { 
    switch (view.getId()) { 
     case R.id.button_green: 
      // todo 
      break; 

     case R.id.button_red: 
      // todo 
      break; 
    } 

}} 

Spero che questo codice sarà aiutare qualcuno

0

Perché non si utilizza coltello da burro?

@Nullable @OnClick({R.id.btn1, R.id.btn2,R.id.btn3, R.id.btn4}) 
public void doStuff(Button button) {} 
+1

Non è ascoltatore onTouchEvent –

+0

'@OnTouch (R.id.view_thing) onTouch pubblico booleano (Visualizza vista, MotionEvent motionEvent) { }' –

5

Con butterknife sarebbe come questo. (nel mio caso ImageView come pulsanti)

@OnTouch({R.id.Button1, R.id.Button2, R.id.Button3}) 
public boolean buttonsTouched(ImageView button, MotionEvent event) { 
    switch (event.getAction()) { 
     case MotionEvent.ACTION_DOWN: 
      --(Your ACTION on Pressed)-- 
      return true; 
     case MotionEvent.ACTION_UP: 
      --(Your ACTION on Release)-- 
      return true; 
    } 
    return true; 
}