2010-08-24 17 views
9

Tengo dos botones que incrementan y disminuyen un valor por uno con cada pulsación y funcionan muy bien con onClickListener. Veo que existe un onLongClickListener, que supongo que es para tocar y mantener eventos. ¿Cómo puedo hacer que el número aumente/disminuya rápidamente si se mantiene presionado el botón?Evento de contacto prolongado de Android

¿Estoy en lo correcto al asumir que onLongClickListener solo dispara una vez por clic prolongado? ¿Hay un oyente más apropiado o una propiedad en alguna parte de la que no tengo conocimiento?

+0

Use Handler.sendDelayedMessage() para publicar un mensaje para usted cada x milisegundos, hasta que obtenga el evento ascendente. – hackbod

+0

Intenta usar http://developer.android.com/reference/android/view/View.OnTouchListener.html En ontouch, te da un evento motivador. Puede verificar la acción hacia abajo y la acción hacia arriba. Básicamente está implementando en touch y onlongtouch usted mismo – Falmarri

+0

Todo lo que quiero es una x-- y TextView.setText cada 200ms más o menos mientras se mantiene presionado un botón. Me disculpo que no tengo tanta experiencia con Java, la mayor parte de mi experiencia ha sido en material de tipo ASP/PHP sin mucha interactividad. Si alguien tiene un código de muestra o podría simplemente indicarme la metodología correcta, lo agradecería enormemente, simplemente no sé por dónde empezar con este. –

Respuesta

15

Puede implementarlo como en el siguiente código.

package org.me.rapidchange; 

import android.app.Activity; 
import android.os.Bundle; 
import android.os.Handler; 
import android.os.Message; 
import android.util.Log; 
import android.view.KeyEvent; 
import android.view.MotionEvent; 
import android.view.View; 
import android.view.View.OnClickListener; 
import android.view.View.OnKeyListener; 
import android.view.View.OnTouchListener; 
import android.widget.Button; 
import android.widget.TextView; 
import java.util.concurrent.Executors; 
import java.util.concurrent.ScheduledExecutorService; 
import java.util.concurrent.TimeUnit; 

public class MainActivity extends Activity implements OnKeyListener, 
     OnTouchListener, OnClickListener { 
    private class UpdateCounterTask implements Runnable { 
     private boolean mInc; 

     public UpdateCounterTask(boolean inc) { 
      mInc = inc; 
     } 

     public void run() { 
      if (mInc) { 
       mHandler.sendEmptyMessage(MSG_INC); 
      } else { 
       mHandler.sendEmptyMessage(MSG_DEC); 
      } 
     } 
    } 

    private static final int MSG_INC = 0; 
    private static final int MSG_DEC = 1; 

    private Button mIncButton; 
    private Button mDecButton; 
    private TextView mText; 
    private int mCounter; 

    private Handler mHandler; 
    private ScheduledExecutorService mUpdater; 

    /** Called when the activity is first created. */ 
    @Override 
    public void onCreate(Bundle icicle) { 
     super.onCreate(icicle); 
     setContentView(R.layout.main); 
     mHandler = new Handler() { 
      @Override 
      public void handleMessage(Message msg) { 
       switch (msg.what) { 
        case MSG_INC: 
         inc(); 
         return; 
        case MSG_DEC: 
         dec(); 
         return; 
       } 
       super.handleMessage(msg); 
      } 
     }; 
     mIncButton = (Button) findViewById(R.id.inc_button); 
     mDecButton = (Button) findViewById(R.id.dec_button); 
     mText = (TextView) findViewById(R.id.text); 
     mIncButton.setOnTouchListener(this); 
     mIncButton.setOnKeyListener(this); 
     mIncButton.setOnClickListener(this); 
     mDecButton.setOnTouchListener(this); 
     mDecButton.setOnKeyListener(this); 
     mDecButton.setOnClickListener(this); 
    } 

    private void inc() { 
     mCounter++; 
     mText.setText(Integer.toString(mCounter)); 
    } 

    private void dec() { 
     mCounter--; 
     mText.setText(Integer.toString(mCounter)); 
    } 

    private void startUpdating(boolean inc) { 
     if (mUpdater != null) { 
      Log.e(getClass().getSimpleName(), "Another executor is still active"); 
      return; 
     } 
     mUpdater = Executors.newSingleThreadScheduledExecutor(); 
     mUpdater.scheduleAtFixedRate(new UpdateCounterTask(inc), 200, 200, 
       TimeUnit.MILLISECONDS); 
    } 

    private void stopUpdating() { 
     mUpdater.shutdownNow(); 
     mUpdater = null; 
    } 

    public void onClick(View v) { 
     if (mUpdater == null) { 
      if (v == mIncButton) { 
       inc(); 
      } else { 
       dec(); 
      } 
     } 
    } 

    public boolean onKey(View v, int keyCode, KeyEvent event) { 
     boolean isKeyOfInterest = keyCode == KeyEvent.KEYCODE_DPAD_CENTER || keyCode == KeyEvent.KEYCODE_ENTER; 
     boolean isReleased = event.getAction() == KeyEvent.ACTION_UP; 
     boolean isPressed = event.getAction() == KeyEvent.ACTION_DOWN 
       && event.getAction() != KeyEvent.ACTION_MULTIPLE; 

     if (isKeyOfInterest && isReleased) { 
      stopUpdating(); 
     } else if (isKeyOfInterest && isPressed) { 
      startUpdating(v == mIncButton); 
     } 
     return false; 
    } 

    public boolean onTouch(View v, MotionEvent event) { 
     boolean isReleased = event.getAction() == MotionEvent.ACTION_UP || event.getAction() == MotionEvent.ACTION_CANCEL; 
     boolean isPressed = event.getAction() == MotionEvent.ACTION_DOWN; 

     if (isReleased) { 
      stopUpdating(); 
     } else if (isPressed) { 
      startUpdating(v == mIncButton); 
     } 
     return false; 
    } 
} 
+0

Esto funciona fantásticamente, y creo que incluso entiendo cómo funciona, jajaja. ¡Gracias! –

5

Tenía este mismo objetivo y terminó usando un OnLongClick para coger la parte hacia abajo para iniciar un evento que se repite a través de un controlador, entonces el OnClick normal a coger la liberación y detenerlo. Funciona maravillosamente para mí.

mOngoingRunnable = new Runnable() { 
    public void run() { 
     // do stuff 
     mHandler.postDelayed(mOngoingRunnable, delayMsecs); 
    } 
}; 

public boolean onLongClick(View view) { 
    mHandler.post(mOngoingRunnable); 
    mOngoing = true; 
    return false; 
} 

public void onClick(View view) { 
    if (mOngoing) { 
     mHandler.removeCallbacks(mOngoingRunnable); 
     mOngoing = false; 
    } 
} 
Cuestiones relacionadas