diff options
Diffstat (limited to 'core/java')
| -rw-r--r-- | core/java/android/view/View.java | 2 | ||||
| -rw-r--r-- | core/java/android/view/ViewGroup.java | 78 |
2 files changed, 79 insertions, 1 deletions
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java index 537c474..ab3413e 100644 --- a/core/java/android/view/View.java +++ b/core/java/android/view/View.java @@ -7338,7 +7338,7 @@ public class View implements Drawable.Callback, Drawable.Callback2, KeyEvent.Cal sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_HOVER_EXIT); // If the window does not have input focus we take away accessibility // focus as soon as the user stop hovering over the view. - if (!mAttachInfo.mHasWindowFocus) { + if (mAttachInfo != null && !mAttachInfo.mHasWindowFocus) { getViewRootImpl().setAccessibilityFocusedHost(null); } } diff --git a/core/java/android/view/ViewGroup.java b/core/java/android/view/ViewGroup.java index 91e945b..1641d4c 100644 --- a/core/java/android/view/ViewGroup.java +++ b/core/java/android/view/ViewGroup.java @@ -1569,6 +1569,43 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager return handled; } + private void exitHoverTargets() { + if (mHoveredSelf || mFirstHoverTarget != null) { + final long now = SystemClock.uptimeMillis(); + MotionEvent event = MotionEvent.obtain(now, now, + MotionEvent.ACTION_HOVER_EXIT, 0.0f, 0.0f, 0); + event.setSource(InputDevice.SOURCE_TOUCHSCREEN); + dispatchHoverEvent(event); + event.recycle(); + } + } + + private void cancelHoverTarget(View view) { + HoverTarget predecessor = null; + HoverTarget target = mFirstHoverTarget; + while (target != null) { + final HoverTarget next = target.next; + if (target.child == view) { + if (predecessor == null) { + mFirstHoverTarget = next; + } else { + predecessor.next = next; + } + target.recycle(); + + final long now = SystemClock.uptimeMillis(); + MotionEvent event = MotionEvent.obtain(now, now, + MotionEvent.ACTION_HOVER_EXIT, 0.0f, 0.0f, 0); + event.setSource(InputDevice.SOURCE_TOUCHSCREEN); + view.dispatchHoverEvent(event); + event.recycle(); + return; + } + predecessor = target; + target = next; + } + } + /** @hide */ @Override protected boolean hasHoveredChild() { @@ -1997,6 +2034,32 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager } } + private void cancelTouchTarget(View view) { + TouchTarget predecessor = null; + TouchTarget target = mFirstTouchTarget; + while (target != null) { + final TouchTarget next = target.next; + if (target.child == view) { + if (predecessor == null) { + mFirstTouchTarget = next; + } else { + predecessor.next = next; + } + target.recycle(); + + final long now = SystemClock.uptimeMillis(); + MotionEvent event = MotionEvent.obtain(now, now, + MotionEvent.ACTION_CANCEL, 0.0f, 0.0f, 0); + event.setSource(InputDevice.SOURCE_TOUCHSCREEN); + view.dispatchTouchEvent(event); + event.recycle(); + return; + } + predecessor = target; + target = next; + } + } + /** * Returns true if a child view can receive pointer events. * @hide @@ -2416,6 +2479,9 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager // first send it an ACTION_CANCEL motion event. cancelAndClearTouchTargets(null); + // Similarly, set ACTION_EXIT to all hover targets and clear them. + exitHoverTargets(); + // In case view is detached while transition is running mLayoutSuppressed = false; @@ -3453,6 +3519,9 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager clearChildFocus = true; } + cancelTouchTarget(view); + cancelHoverTarget(view); + if (view.getAnimation() != null || (mTransitioningViews != null && mTransitioningViews.contains(view))) { addDisappearingView(view); @@ -3533,6 +3602,9 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager clearChildFocus = view; } + cancelTouchTarget(view); + cancelHoverTarget(view); + if (view.getAnimation() != null || (mTransitioningViews != null && mTransitioningViews.contains(view))) { addDisappearingView(view); @@ -3603,6 +3675,9 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager clearChildFocus = view; } + cancelTouchTarget(view); + cancelHoverTarget(view); + if (view.getAnimation() != null || (mTransitioningViews != null && mTransitioningViews.contains(view))) { addDisappearingView(view); @@ -3648,6 +3723,9 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager child.clearFocus(); } + cancelTouchTarget(child); + cancelHoverTarget(child); + if ((animate && child.getAnimation() != null) || (mTransitioningViews != null && mTransitioningViews.contains(child))) { addDisappearingView(child); |
