aboutsummaryrefslogtreecommitdiffstats
path: root/libs/emojicon/src/main/java/github/ankushsachdeva/emojicon/RepeatTouchListener.java
diff options
context:
space:
mode:
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.java74
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;
+ }
+}