summaryrefslogtreecommitdiffstats
path: root/core/java/android/view/View.java
diff options
context:
space:
mode:
authorAdam Powell <adamp@google.com>2013-07-18 19:42:41 -0700
committerAdam Powell <adamp@google.com>2013-09-05 00:55:20 +0000
commit1487466dc2ce14cccf0ff2bd2f824238aaa0044e (patch)
tree4bf31a9b198846b45f9a15b3ebc53532bb748e6b /core/java/android/view/View.java
parent7f71206d009e737e91c4c767183befe6006497c6 (diff)
downloadframeworks_base-1487466dc2ce14cccf0ff2bd2f824238aaa0044e.zip
frameworks_base-1487466dc2ce14cccf0ff2bd2f824238aaa0044e.tar.gz
frameworks_base-1487466dc2ce14cccf0ff2bd2f824238aaa0044e.tar.bz2
Add View#cancelPendingInputEvents API
This API allows an application to cancel deferred high-level input events already in flight. It forms one tool of several to help apps debounce input events and prevent things like multiple startActivity calls, FragmentTransactions, etc. from executing when only one was desired since it's otherwise not desirable for things like click events to fire synchronously. Change-Id: I60b12cd5350898065f0019d616e24d779eb8cff9
Diffstat (limited to 'core/java/android/view/View.java')
-rw-r--r--core/java/android/view/View.java66
1 files changed, 66 insertions, 0 deletions
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index f2b3e89..398ad17 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -57,6 +57,7 @@ import android.util.LongSparseLongArray;
import android.util.Pools.SynchronizedPool;
import android.util.Property;
import android.util.SparseArray;
+import android.util.SuperNotCalledException;
import android.util.TypedValue;
import android.view.ContextMenu.ContextMenuInfo;
import android.view.AccessibilityIterators.TextSegmentIterator;
@@ -2204,6 +2205,12 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
*/
static final int PFLAG3_MEASURE_NEEDED_BEFORE_LAYOUT = 0x8;
+ /**
+ * Flag indicating that an overridden method correctly called down to
+ * the superclass implementation as required by the API spec.
+ */
+ static final int PFLAG3_CALLED_SUPER = 0x10;
+
/* End of masks for mPrivateFlags3 */
@@ -5955,6 +5962,10 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
// Invalidate too, since the default behavior for views is to be
// be drawn at 50% alpha rather than to change the drawable.
invalidate(true);
+
+ if (!enabled) {
+ cancelPendingInputEvents();
+ }
}
/**
@@ -12364,6 +12375,61 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
}
/**
+ * Cancel any deferred high-level input events that were previously posted to the event queue.
+ *
+ * <p>Many views post high-level events such as click handlers to the event queue
+ * to run deferred in order to preserve a desired user experience - clearing visible
+ * pressed states before executing, etc. This method will abort any events of this nature
+ * that are currently in flight.</p>
+ *
+ * <p>Custom views that generate their own high-level deferred input events should override
+ * {@link #onCancelPendingInputEvents()} and remove those pending events from the queue.</p>
+ *
+ * <p>This will also cancel pending input events for any child views.</p>
+ *
+ * <p>Note that this may not be sufficient as a debouncing strategy for clicks in all cases.
+ * This will not impact newer events posted after this call that may occur as a result of
+ * lower-level input events still waiting in the queue. If you are trying to prevent
+ * double-submitted events for the duration of some sort of asynchronous transaction
+ * you should also take other steps to protect against unexpected double inputs e.g. calling
+ * {@link #setEnabled(boolean) setEnabled(false)} and re-enabling the view when
+ * the transaction completes, tracking already submitted transaction IDs, etc.</p>
+ */
+ public final void cancelPendingInputEvents() {
+ dispatchCancelPendingInputEvents();
+ }
+
+ /**
+ * Called by {@link #cancelPendingInputEvents()} to cancel input events in flight.
+ * Overridden by ViewGroup to dispatch. Package scoped to prevent app-side meddling.
+ */
+ void dispatchCancelPendingInputEvents() {
+ mPrivateFlags3 &= ~PFLAG3_CALLED_SUPER;
+ onCancelPendingInputEvents();
+ if ((mPrivateFlags3 & PFLAG3_CALLED_SUPER) != PFLAG3_CALLED_SUPER) {
+ throw new SuperNotCalledException("View " + getClass().getSimpleName() +
+ " did not call through to super.onCancelPendingInputEvents()");
+ }
+ }
+
+ /**
+ * Called as the result of a call to {@link #cancelPendingInputEvents()} on this view or
+ * a parent view.
+ *
+ * <p>This method is responsible for removing any pending high-level input events that were
+ * posted to the event queue to run later. Custom view classes that post their own deferred
+ * high-level events via {@link #post(Runnable)}, {@link #postDelayed(Runnable, long)} or
+ * {@link android.os.Handler} should override this method, call
+ * <code>super.onCancelPendingInputEvents()</code> and remove those callbacks as appropriate.
+ * </p>
+ */
+ public void onCancelPendingInputEvents() {
+ removePerformClickCallback();
+ cancelLongPress();
+ mPrivateFlags3 |= PFLAG3_CALLED_SUPER;
+ }
+
+ /**
* Store this view hierarchy's frozen state into the given container.
*
* @param container The SparseArray in which to save the view's state.