2010-08-24 30 views
9

Mam dwa przyciski, które zwiększają i zmniejszają wartość o jeden przy każdym naciśnięciu i działają dobrze z funkcją onClickListener. Widzę, że istnieje onLongClickListener, który, jak przypuszczam, dotyczy zdarzeń dotyku i wstrzymania. Jak miałbym szybko zwiększać/zmniejszać liczbę, jeśli przycisk jest trzymany?Dotykowe wydarzenie z Androidem

Czy mam rację przyjmując, że onLongClickListener strzela tylko raz na jedno długie kliknięcie? Czy jest gdzieś bardziej odpowiedni słuchacz lub własność, której nie znam?

+0

Użyj funkcji Handler.sendDelayedMessage(), aby wysłać wiadomość do siebie co x milisekundy, dopóki nie pojawi się zdarzenie up. – hackbod

+0

Spróbuj użyć http://developer.android.com/reference/android/view/View.OnTouchListener.html W ontouch, daje to motionevent. Możesz sprawdzić, czy nie działa akcja i akcja. Zasadniczo wdrażasz na zasadzie touch i onlongtouch. – Falmarri

+0

Wszystko, czego chcę, to x-- i TextView.setText co 200 ms, gdy przycisk jest wciśnięty. Przepraszam, nie jestem doświadczony w Javie, większość moich doświadczeń była w rzeczach typu ASP/PHP bez dużej interaktywności. Jeśli ktoś ma przykładowy kod lub może wskazać mi właściwą metodologię, byłbym bardzo wdzięczny, po prostu nie wiem nawet, od czego zacząć. –

Odpowiedz

15

Można go zaimplementować w następujący sposób.

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

Działa to fantastycznie, i myślę, że nawet rozumiem, jak to działa, lol. Dzięki! –

5

miałem ten sam cel, co skończyło się używając OnLongClick złapać część dół, aby rozpocząć powtarzające się zdarzenia za pomocą obsługi, to normalne OnClick złapać i zatrzymać jej uwolnienie. Działa pięknie dla mnie.

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; 
    } 
} 
Powiązane problemy