summaryrefslogtreecommitdiff
path: root/core/java/android/view/ViewGroup.java
diff options
context:
space:
mode:
authorEvan Rosky <erosky@google.com>2018-03-22 16:04:15 -0700
committerEvan Rosky <erosky@google.com>2018-03-30 19:52:58 +0000
commit4807ae257b930bec1b485882dfb18329f7ca07af (patch)
treeed61a43fecd8902404129501f89e7eae2ce3e9e1 /core/java/android/view/ViewGroup.java
parent2ed9bf437e22de7ea87697f84bb1ea39bf765612 (diff)
Renamed KeyFallbackEvent to UnhandledKeyEvent and exposed dispatch
This new naming clashes less with the existing notion of FLAG_FALLBACK in KeyEvents. Bug: 72562800 Test: ViewTest#testUnhandledKeys Change-Id: Ibd713860601e62d955443fe6811fd974b5bb0092
Diffstat (limited to 'core/java/android/view/ViewGroup.java')
-rw-r--r--core/java/android/view/ViewGroup.java68
1 files changed, 68 insertions, 0 deletions
diff --git a/core/java/android/view/ViewGroup.java b/core/java/android/view/ViewGroup.java
index 33fcf6a74aa1..6002fe512a28 100644
--- a/core/java/android/view/ViewGroup.java
+++ b/core/java/android/view/ViewGroup.java
@@ -583,6 +583,11 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
private List<Integer> mTransientIndices = null;
private List<View> mTransientViews = null;
+ /**
+ * Keeps track of how many child views have UnhandledKeyEventListeners. This should only be
+ * updated on the UI thread so shouldn't require explicit synchronization.
+ */
+ int mChildUnhandledKeyListeners = 0;
/**
* Empty ActionMode used as a sentinel in recursive entries to startActionModeForChild.
@@ -5055,6 +5060,9 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
child.assignParent(this);
} else {
child.mParent = this;
+ if (child.hasUnhandledKeyListener()) {
+ incrementChildUnhandledKeyListeners();
+ }
}
final boolean childHasFocus = child.hasFocus();
@@ -5359,6 +5367,10 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
removeFromArray(index);
+ if (view.hasUnhandledKeyListener()) {
+ decrementChildUnhandledKeyListeners();
+ }
+
if (view == mDefaultFocus) {
clearDefaultFocus(view);
}
@@ -7537,6 +7549,62 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
}
}
+ @Override
+ boolean hasUnhandledKeyListener() {
+ return (mChildUnhandledKeyListeners > 0) || super.hasUnhandledKeyListener();
+ }
+
+ void incrementChildUnhandledKeyListeners() {
+ mChildUnhandledKeyListeners += 1;
+ if (mChildUnhandledKeyListeners == 1) {
+ if (mParent instanceof ViewGroup) {
+ ((ViewGroup) mParent).incrementChildUnhandledKeyListeners();
+ }
+ }
+ }
+
+ void decrementChildUnhandledKeyListeners() {
+ mChildUnhandledKeyListeners -= 1;
+ if (mChildUnhandledKeyListeners == 0) {
+ if (mParent instanceof ViewGroup) {
+ ((ViewGroup) mParent).decrementChildUnhandledKeyListeners();
+ }
+ }
+ }
+
+ @Override
+ View dispatchUnhandledKeyEvent(KeyEvent evt) {
+ if (!hasUnhandledKeyListener()) {
+ return null;
+ }
+ ArrayList<View> orderedViews = buildOrderedChildList();
+ if (orderedViews != null) {
+ try {
+ for (int i = orderedViews.size() - 1; i >= 0; --i) {
+ View v = orderedViews.get(i);
+ View consumer = v.dispatchUnhandledKeyEvent(evt);
+ if (consumer != null) {
+ return consumer;
+ }
+ }
+ } finally {
+ orderedViews.clear();
+ }
+ } else {
+ for (int i = getChildCount() - 1; i >= 0; --i) {
+ View v = getChildAt(i);
+ View consumer = v.dispatchUnhandledKeyEvent(evt);
+ if (consumer != null) {
+ return consumer;
+ }
+ }
+ }
+ if (onUnhandledKeyEvent(evt)) {
+ return this;
+ }
+ return null;
+ }
+
/**
* LayoutParams are used by views to tell their parents how they want to be
* laid out. See