2010-08-24 9 views
9

Ich habe zwei Schaltflächen, die bei jedem Drücken einen Wert um eins erhöhen oder verringern, und sie funktionieren problemlos mit dem onClickListener. Ich sehe, dass ein onLongClickListener existiert, von dem ich annehme, dass er für Berührungsereignisse ist. Wie würde ich die Nummer schnell erhöhen/verringern, wenn die Taste gedrückt wird?Android Long-Touch-Ereignis

Bin ich richtig davon ausgegangen, dass onLongClickListener nur einmal pro langen Klick ausgelöst wird? Gibt es irgendwo einen besseren Hörer oder eine Eigenschaft, die ich nicht kenne?

+0

Verwenden Sie Handler.sendDelayedMessage(), um alle x Millisekunden eine Nachricht an sich selbst zu senden, bis Sie das Ereignis up erhalten. – hackbod

+0

Versuchen Sie es mit http://developer.android.com/reference/android/view/View.OnTouchListener.html In ontouch gibt es Ihnen ein Motionevent. Sie können nach unten und nach oben suchen. Sie implementieren im Wesentlichen auf Touch und onlongtouch selbst – Falmarri

+0

Alles was ich will ist ein x-- und ein TextView.setText alle 200ms oder so, während eine Taste gedrückt gehalten wird. Ich entschuldige mich, ich bin nicht so erfahren mit Java, die meisten meiner Erfahrung war in ASP/PHP-Art Zeug ohne viel Interaktivität. Wenn jemand vielleicht einen Beispielcode hat oder mir einfach die richtige Methode zeigen könnte, würde ich es sehr schätzen, ich weiß einfach nicht einmal, wo ich mit diesem beginnen soll. –

Antwort

15

Sie können es wie im folgenden Code implementieren.

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

Das funktioniert fantastisch, und ich glaube, ich verstehe sogar, wie es funktioniert, lol. Vielen Dank! –

5

Ich hatte das gleiche Ziel und landete einen OnLongClick mit dem nach unten Teil fangen ein sich wiederholendes Ereignis über einen Handler zu starten, dann die normale OnClick die Freigabe zu fangen und ihn zu stoppen. Funktioniert wunderbar für mich.

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; 
    } 
} 
Verwandte Themen