diff options
Diffstat (limited to 'libs/emojicon/src/main/java/github/ankushsachdeva/emojicon/RepeatTouchListener.java')
-rw-r--r-- | libs/emojicon/src/main/java/github/ankushsachdeva/emojicon/RepeatTouchListener.java | 74 |
1 files changed, 74 insertions, 0 deletions
diff --git a/libs/emojicon/src/main/java/github/ankushsachdeva/emojicon/RepeatTouchListener.java b/libs/emojicon/src/main/java/github/ankushsachdeva/emojicon/RepeatTouchListener.java new file mode 100644 index 00000000..e8f8e0fb --- /dev/null +++ b/libs/emojicon/src/main/java/github/ankushsachdeva/emojicon/RepeatTouchListener.java @@ -0,0 +1,74 @@ +package github.ankushsachdeva.emojicon; + +import android.os.Handler; +import android.os.SystemClock; +import android.view.MotionEvent; +import android.view.View; + +/** + * A class, that can be used as a TouchListener on any view (e.g. a Button). + * It cyclically runs a clickListener, emulating keyboard-like behaviour. First + * click is fired immediately, next before initialInterval, and subsequent before + * normalInterval. + * <p/> + * <p>Interval is scheduled before the onClick completes, so it has to run fast. + * If it runs slow, it does not generate skipped onClicks. + */ +class RepeatTouchListener implements View.OnTouchListener { + + private Handler handler = new Handler(); + + private int initialInterval; + private final int normalInterval; + private final View.OnClickListener clickListener; + + private Runnable handlerRunnable = new Runnable() { + @Override + public void run() { + if (downView == null) { + return; + } + handler.removeCallbacksAndMessages(downView); + handler.postAtTime(this, downView, SystemClock.uptimeMillis() + normalInterval); + clickListener.onClick(downView); + } + }; + + private View downView; + + /** + * @param initialInterval The interval before first click event + * @param normalInterval The interval before second and subsequent click + * events + * @param clickListener The OnClickListener, that will be called + * periodically + */ + public RepeatTouchListener(int initialInterval, int normalInterval, View.OnClickListener clickListener) { + if (clickListener == null) + throw new IllegalArgumentException("null runnable"); + if (initialInterval < 0 || normalInterval < 0) + throw new IllegalArgumentException("negative interval"); + + this.initialInterval = initialInterval; + this.normalInterval = normalInterval; + this.clickListener = clickListener; + } + + public boolean onTouch(View view, MotionEvent motionEvent) { + switch (motionEvent.getAction()) { + case MotionEvent.ACTION_DOWN: + downView = view; + handler.removeCallbacks(handlerRunnable); + handler.postAtTime(handlerRunnable, downView, SystemClock.uptimeMillis() + initialInterval); + clickListener.onClick(view); + return true; + case MotionEvent.ACTION_UP: + case MotionEvent.ACTION_CANCEL: + case MotionEvent.ACTION_OUTSIDE: + handler.removeCallbacksAndMessages(downView); + downView = null; + return true; + } + return false; + } +} |