am bc6c050f: Merge "Fix touch processing for Overlay views" into jb-mr2-dev
* commit 'bc6c050f9c603159c526cc7d60ec9159c57359e7': Fix touch processing for Overlay views
This commit is contained in:
@@ -18,9 +18,10 @@ package android.view;
|
||||
import android.graphics.drawable.Drawable;
|
||||
|
||||
/**
|
||||
* An overlay is an extra layer that sits on top of a View (the "host view") which is drawn after
|
||||
* all other content in that view (including children, if the view is a ViewGroup). Interaction
|
||||
* with the overlay layer is done in terms of adding/removing views and drawables.
|
||||
* An overlay is an extra layer that sits on top of a View (the "host view")
|
||||
* which is drawn after all other content in that view (including children,
|
||||
* if the view is a ViewGroup). Interaction with the overlay layer is done in
|
||||
* terms of adding/removing views and drawables.
|
||||
*
|
||||
* @see android.view.View#getOverlay()
|
||||
*/
|
||||
@@ -47,10 +48,16 @@ public interface Overlay {
|
||||
void remove(Drawable drawable);
|
||||
|
||||
/**
|
||||
* Adds a View to the overlay. The bounds of the added view should be relative to
|
||||
* the host view. Any view added to the overlay should be removed when it is no longer
|
||||
* needed or no longer visible. The view must not be parented elsewhere when it is added
|
||||
* to the overlay.
|
||||
* Adds a View to the overlay. The bounds of the added view should be
|
||||
* relative to the host view. Any view added to the overlay should be
|
||||
* removed when it is no longer needed or no longer visible.
|
||||
*
|
||||
* <p>If the view has a parent, the view will be removed from that parent
|
||||
* before being added to the overlay. Also, the view will be repositioned
|
||||
* such that it is in the same relative location inside the activity. For
|
||||
* example, if the view's current parent lies 100 pixels to the right
|
||||
* and 200 pixels down from the origin of the overlay's
|
||||
* host view, then the view will be offset by (100, 200).</p>
|
||||
*
|
||||
* @param view The View to be added to the overlay. The added view will be
|
||||
* drawn when the overlay is drawn.
|
||||
|
||||
@@ -12098,7 +12098,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
|
||||
//System.out.println("Attached! " + this);
|
||||
mAttachInfo = info;
|
||||
if (mOverlay != null) {
|
||||
mOverlay.mAttachInfo = info;
|
||||
mOverlay.dispatchAttachedToWindow(info, visibility);
|
||||
}
|
||||
mWindowAttachCount++;
|
||||
// We will need to evaluate the drawable state at least once.
|
||||
@@ -12169,7 +12169,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
|
||||
|
||||
mAttachInfo = null;
|
||||
if (mOverlay != null) {
|
||||
mOverlay.mAttachInfo = null;
|
||||
mOverlay.dispatchDetachedFromWindow();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1868,13 +1868,37 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
|
||||
// have become out of sync.
|
||||
removePointersFromTouchTargets(idBitsToAssign);
|
||||
|
||||
final float x = ev.getX(actionIndex);
|
||||
final float y = ev.getY(actionIndex);
|
||||
|
||||
if (mOverlay != null) {
|
||||
ViewOverlay overlay = (ViewOverlay) mOverlay;
|
||||
// Check to see whether the overlay can handle the event
|
||||
final View child = mOverlay;
|
||||
if (canViewReceivePointerEvents(child) &&
|
||||
isTransformedTouchPointInView(x, y, child, null)) {
|
||||
newTouchTarget = getTouchTarget(child);
|
||||
if (newTouchTarget != null) {
|
||||
newTouchTarget.pointerIdBits |= idBitsToAssign;
|
||||
} else {
|
||||
resetCancelNextUpFlag(child);
|
||||
if (dispatchTransformedTouchEvent(ev, false, child,
|
||||
idBitsToAssign)) {
|
||||
mLastTouchDownTime = ev.getDownTime();
|
||||
mLastTouchDownX = ev.getX();
|
||||
mLastTouchDownY = ev.getY();
|
||||
newTouchTarget = addTouchTarget(child, idBitsToAssign);
|
||||
alreadyDispatchedToNewTouchTarget = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
final int childrenCount = mChildrenCount;
|
||||
if (childrenCount != 0 || mOverlay != null) {
|
||||
if (newTouchTarget == null && childrenCount != 0) {
|
||||
// Find a child that can receive the event.
|
||||
// Scan children from front to back.
|
||||
final View[] children = mChildren;
|
||||
final float x = ev.getX(actionIndex);
|
||||
final float y = ev.getY(actionIndex);
|
||||
|
||||
final boolean customOrder = isChildrenDrawingOrderEnabled();
|
||||
for (int i = childrenCount - 1; i >= 0; i--) {
|
||||
@@ -1906,27 +1930,6 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (mOverlay != null && newTouchTarget == null) {
|
||||
// Check to see whether the overlay can handle the event
|
||||
final View child = mOverlay;
|
||||
if (canViewReceivePointerEvents(child) &&
|
||||
isTransformedTouchPointInView(x, y, child, null)) {
|
||||
newTouchTarget = getTouchTarget(child);
|
||||
if (newTouchTarget != null) {
|
||||
newTouchTarget.pointerIdBits |= idBitsToAssign;
|
||||
} else {
|
||||
resetCancelNextUpFlag(child);
|
||||
if (dispatchTransformedTouchEvent(ev, false, child,
|
||||
idBitsToAssign)) {
|
||||
mLastTouchDownTime = ev.getDownTime();
|
||||
mLastTouchDownX = ev.getX();
|
||||
mLastTouchDownY = ev.getY();
|
||||
newTouchTarget = addTouchTarget(child, idBitsToAssign);
|
||||
alreadyDispatchedToNewTouchTarget = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (newTouchTarget == null && mFirstTouchTarget != null) {
|
||||
@@ -1957,7 +1960,7 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
|
||||
handled = true;
|
||||
} else {
|
||||
final boolean cancelChild = resetCancelNextUpFlag(target.child)
|
||||
|| intercepted;
|
||||
|| intercepted;
|
||||
if (dispatchTransformedTouchEvent(ev, cancelChild,
|
||||
target.child, target.pointerIdBits)) {
|
||||
handled = true;
|
||||
|
||||
@@ -23,17 +23,21 @@ import android.graphics.drawable.Drawable;
|
||||
import java.util.ArrayList;
|
||||
|
||||
/**
|
||||
* ViewOverlay is a container that View uses to host all objects (views and drawables) that
|
||||
* are added to its "overlay", gotten through {@link View#getOverlay()}. Views and drawables are
|
||||
* added to the overlay via the add/remove methods in this class. These views and drawables are
|
||||
* drawn whenever the view itself is drawn; first the view draws its own content (and children,
|
||||
* if it is a ViewGroup), then it draws its overlay (if it has one).
|
||||
* ViewOverlay is a container that View uses to host all objects (views and
|
||||
* drawables) that are added to its "overlay", gotten through
|
||||
* {@link View#getOverlay()}. Views and drawables are added to the overlay
|
||||
* via the add/remove methods in this class. These views and drawables are
|
||||
* drawn whenever the view itself is drawn; first the view draws its own
|
||||
* content (and children, if it is a ViewGroup), then it draws its overlay
|
||||
* (if it has one).
|
||||
*
|
||||
* Besides managing and drawing the list of drawables, this class serves two purposes:
|
||||
* Besides managing and drawing the list of drawables, this class serves
|
||||
* two purposes:
|
||||
* (1) it noops layout calls because children are absolutely positioned and
|
||||
* (2) it forwards all invalidation calls to its host view. The invalidation redirect is
|
||||
* necessary because the overlay is not a child of the host view and invalidation cannot
|
||||
* therefore follow the normal path up through the parent hierarchy.
|
||||
* (2) it forwards all invalidation calls to its host view. The invalidation
|
||||
* redirect is necessary because the overlay is not a child of the host view
|
||||
* and invalidation cannot therefore follow the normal path up through the
|
||||
* parent hierarchy.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
@@ -85,6 +89,22 @@ class ViewOverlay extends ViewGroup implements Overlay {
|
||||
|
||||
@Override
|
||||
public void add(View child) {
|
||||
int deltaX = 0;
|
||||
int deltaY = 0;
|
||||
if (child.getParent() instanceof ViewGroup) {
|
||||
ViewGroup parent = (ViewGroup) child.getParent();
|
||||
if (parent != mHostView) {
|
||||
// Moving to different container; figure out how to position child such that
|
||||
// it is in the same location on the screen
|
||||
int[] parentLocation = new int[2];
|
||||
int[] hostViewLocation = new int[2];
|
||||
parent.getLocationOnScreen(parentLocation);
|
||||
mHostView.getLocationOnScreen(hostViewLocation);
|
||||
child.offsetLeftAndRight(parentLocation[0] - hostViewLocation[0]);
|
||||
child.offsetTopAndBottom(parentLocation[1] - hostViewLocation[1]);
|
||||
}
|
||||
parent.removeView(child);
|
||||
}
|
||||
super.addView(child);
|
||||
}
|
||||
|
||||
@@ -133,7 +153,6 @@ class ViewOverlay extends ViewGroup implements Overlay {
|
||||
public void invalidate(Rect dirty) {
|
||||
super.invalidate(dirty);
|
||||
if (mHostView != null) {
|
||||
dirty.offset(getLeft(), getTop());
|
||||
mHostView.invalidate(dirty);
|
||||
}
|
||||
}
|
||||
@@ -203,7 +222,15 @@ class ViewOverlay extends ViewGroup implements Overlay {
|
||||
@Override
|
||||
public ViewParent invalidateChildInParent(int[] location, Rect dirty) {
|
||||
if (mHostView != null) {
|
||||
mHostView.invalidate(dirty);
|
||||
dirty.offset(location[0], location[1]);
|
||||
if (mHostView instanceof ViewGroup) {
|
||||
location[0] = 0;
|
||||
location[1] = 0;
|
||||
super.invalidateChildInParent(location, dirty);
|
||||
return ((ViewGroup) mHostView).invalidateChildInParent(location, dirty);
|
||||
} else {
|
||||
invalidate(dirty);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user