diff options
-rw-r--r-- | api/current.txt | 21 | ||||
-rw-r--r-- | core/java/android/animation/RectEvaluator.java | 2 | ||||
-rw-r--r-- | core/java/android/view/View.java | 44 | ||||
-rw-r--r-- | core/java/android/view/ViewGroup.java | 57 | ||||
-rw-r--r-- | core/java/android/view/ViewGroupOverlay.java (renamed from core/java/android/view/Overlay.java) | 60 | ||||
-rw-r--r-- | core/java/android/view/ViewOverlay.java | 393 |
6 files changed, 316 insertions, 261 deletions
diff --git a/api/current.txt b/api/current.txt index c9ef978..7fe166e 100644 --- a/api/current.txt +++ b/api/current.txt @@ -24966,14 +24966,6 @@ package android.view { field public static final int ORIENTATION_UNKNOWN = -1; // 0xffffffff } - public abstract interface Overlay { - method public abstract void add(android.graphics.drawable.Drawable); - method public abstract void add(android.view.View); - method public abstract void clear(); - method public abstract void remove(android.graphics.drawable.Drawable); - method public abstract void remove(android.view.View); - } - public class ScaleGestureDetector { ctor public ScaleGestureDetector(android.content.Context, android.view.ScaleGestureDetector.OnScaleGestureListener); method public float getCurrentSpan(); @@ -25278,7 +25270,7 @@ package android.view { method public int getNextFocusUpId(); method public android.view.View.OnFocusChangeListener getOnFocusChangeListener(); method public int getOverScrollMode(); - method public android.view.Overlay getOverlay(); + method public android.view.ViewOverlay getOverlay(); method public int getPaddingBottom(); method public int getPaddingEnd(); method public int getPaddingLeft(); @@ -26019,12 +26011,23 @@ package android.view { method public abstract void onChildViewRemoved(android.view.View, android.view.View); } + public class ViewGroupOverlay extends android.view.ViewOverlay { + method public void add(android.view.View); + method public void remove(android.view.View); + } + public abstract interface ViewManager { method public abstract void addView(android.view.View, android.view.ViewGroup.LayoutParams); method public abstract void removeView(android.view.View); method public abstract void updateViewLayout(android.view.View, android.view.ViewGroup.LayoutParams); } + public class ViewOverlay { + method public void add(android.graphics.drawable.Drawable); + method public void clear(); + method public void remove(android.graphics.drawable.Drawable); + } + public abstract interface ViewParent { method public abstract void bringChildToFront(android.view.View); method public abstract void childDrawableStateChanged(android.view.View); diff --git a/core/java/android/animation/RectEvaluator.java b/core/java/android/animation/RectEvaluator.java index 10932bb..28d496b 100644 --- a/core/java/android/animation/RectEvaluator.java +++ b/core/java/android/animation/RectEvaluator.java @@ -18,7 +18,7 @@ package android.animation; import android.graphics.Rect; /** - * This evaluator can be used to perform type interpolation between <code>int</code> values. + * This evaluator can be used to perform type interpolation between <code>Rect</code> values. */ public class RectEvaluator implements TypeEvaluator<Rect> { diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java index 3b06da7..a520e17 100644 --- a/core/java/android/view/View.java +++ b/core/java/android/view/View.java @@ -12107,7 +12107,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, //System.out.println("Attached! " + this); mAttachInfo = info; if (mOverlay != null) { - mOverlay.dispatchAttachedToWindow(info, visibility); + mOverlay.getOverlayView().dispatchAttachedToWindow(info, visibility); } mWindowAttachCount++; // We will need to evaluate the drawable state at least once. @@ -12178,7 +12178,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, mAttachInfo = null; if (mOverlay != null) { - mOverlay.dispatchDetachedFromWindow(); + mOverlay.getOverlayView().dispatchDetachedFromWindow(); } } @@ -12831,7 +12831,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, if ((mPrivateFlags & PFLAG_SKIP_DRAW) == PFLAG_SKIP_DRAW) { dispatchDraw(canvas); if (mOverlay != null && !mOverlay.isEmpty()) { - mOverlay.draw(canvas); + mOverlay.getOverlayView().draw(canvas); } } else { draw(canvas); @@ -13147,7 +13147,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, mPrivateFlags &= ~PFLAG_DIRTY_MASK; dispatchDraw(canvas); if (mOverlay != null && !mOverlay.isEmpty()) { - mOverlay.draw(canvas); + mOverlay.getOverlayView().draw(canvas); } } else { draw(canvas); @@ -13905,7 +13905,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, onDrawScrollBars(canvas); if (mOverlay != null && !mOverlay.isEmpty()) { - mOverlay.dispatchDraw(canvas); + mOverlay.getOverlayView().dispatchDraw(canvas); } // we're done... @@ -14049,34 +14049,24 @@ public class View implements Drawable.Callback, KeyEvent.Callback, onDrawScrollBars(canvas); if (mOverlay != null && !mOverlay.isEmpty()) { - mOverlay.dispatchDraw(canvas); + mOverlay.getOverlayView().dispatchDraw(canvas); } } /** - * Called by the addToOverlay() methods to create, attach, and size the overlay as necessary + * Returns the overlay for this view, creating it if it does not yet exist. + * Adding drawables to the overlay will cause them to be displayed whenever + * the view itself is redrawn. Objects in the overlay should be actively + * managed: remove them when they should not be displayed anymore. The + * overlay will always have the same size as its host view. + * + * @return The ViewOverlay object for this view. + * @see ViewOverlay */ - private void setupOverlay() { + public ViewOverlay getOverlay() { if (mOverlay == null) { mOverlay = new ViewOverlay(mContext, this); - mOverlay.mAttachInfo = mAttachInfo; - mOverlay.setRight(mRight); - mOverlay.setBottom(mBottom); } - } - - /** - * Returns the overlay for this view, creating it if it does not yet exist. Adding drawables - * and/or views to the overlay will cause them to be displayed whenever the view itself is - * redrawn. Objects in the overlay should be actively managed: remove them when they should - * not be displayed anymore and invalidate this view appropriately when overlay drawables - * change. The overlay will always have the same size as its host view. - * - * @return The Overlay object for this view. - * @see Overlay - */ - public Overlay getOverlay() { - setupOverlay(); return mOverlay; } @@ -14360,8 +14350,8 @@ public class View implements Drawable.Callback, KeyEvent.Callback, private void sizeChange(int newWidth, int newHeight, int oldWidth, int oldHeight) { onSizeChanged(newWidth, newHeight, oldWidth, oldHeight); if (mOverlay != null) { - mOverlay.setRight(mRight); - mOverlay.setBottom(mBottom); + mOverlay.getOverlayView().setRight(newWidth); + mOverlay.getOverlayView().setBottom(newHeight); } } diff --git a/core/java/android/view/ViewGroup.java b/core/java/android/view/ViewGroup.java index f615e1bc..c07191a 100644 --- a/core/java/android/view/ViewGroup.java +++ b/core/java/android/view/ViewGroup.java @@ -1876,34 +1876,10 @@ 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 (newTouchTarget == null && childrenCount != 0) { + final float x = ev.getX(actionIndex); + final float y = ev.getY(actionIndex); // Find a child that can receive the event. // Scan children from front to back. final View[] children = mChildren; @@ -2991,6 +2967,26 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager } /** + * Returns the ViewGroupOverlay for this view group, creating it if it does + * not yet exist. In addition to {@link ViewOverlay}'s support for drawables, + * {@link ViewGroupOverlay} allows views to be added to the overlay. These + * views, like overlay drawables, are visual-only; they do not receive input + * events and should not be used as anything other than a temporary + * representation of a view in a parent container, such as might be used + * by an animation effect. + * + * @return The ViewGroupOverlay object for this view. + * @see ViewGroupOverlay + */ + @Override + public ViewGroupOverlay getOverlay() { + if (mOverlay == null) { + mOverlay = new ViewGroupOverlay(mContext, this); + } + return (ViewGroupOverlay) mOverlay; + } + + /** * Returns the index of the child to draw for this iteration. Override this * if you want to change the drawing order of children. By default, it * returns i. @@ -3055,11 +3051,12 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager } } if (mOverlay != null) { - mOverlay.mRecreateDisplayList = (mOverlay.mPrivateFlags & PFLAG_INVALIDATED) + View overlayView = mOverlay.getOverlayView(); + overlayView.mRecreateDisplayList = (overlayView.mPrivateFlags & PFLAG_INVALIDATED) == PFLAG_INVALIDATED; - mOverlay.mPrivateFlags &= ~PFLAG_INVALIDATED; - mOverlay.getDisplayList(); - mOverlay.mRecreateDisplayList = false; + overlayView.mPrivateFlags &= ~PFLAG_INVALIDATED; + overlayView.getDisplayList(); + overlayView.mRecreateDisplayList = false; } } diff --git a/core/java/android/view/Overlay.java b/core/java/android/view/ViewGroupOverlay.java index 6630752..c1b24f2 100644 --- a/core/java/android/view/Overlay.java +++ b/core/java/android/view/ViewGroupOverlay.java @@ -15,43 +15,37 @@ */ package android.view; +import android.content.Context; 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. + * A group overlay is an extra layer that sits on top of a ViewGroup + * (the "host view") which is drawn after all other content in that view + * (including the view group's children). Interaction with the overlay + * layer is done by adding and removing views and drawables. * - * @see android.view.View#getOverlay() + * <p>ViewGroupOverlay is a subclass of {@link ViewOverlay}, adding the ability to + * manage views for overlays on ViewGroups, in addition to the drawable + * support in ViewOverlay.</p> + * + * @see ViewGroup#getOverlay() */ -public interface Overlay { +public class ViewGroupOverlay extends ViewOverlay { - /** - * Adds a Drawable to the overlay. The bounds of the drawable should be relative to - * the host view. Any drawable added to the overlay should be removed when it is no longer - * needed or no longer visible. - * - * @param drawable The Drawable to be added to the overlay. This drawable will be - * drawn when the view redraws its overlay. - * @see #remove(android.graphics.drawable.Drawable) - * @see #add(View) - */ - void add(Drawable drawable); - - /** - * Removes the specified Drawable from the overlay. - * - * @param drawable The Drawable to be removed from the overlay. - * @see #add(android.graphics.drawable.Drawable) - */ - void remove(Drawable drawable); + ViewGroupOverlay(Context context, View hostView) { + super(context, hostView); + } /** * 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>Views in the overlay are visual-only; they do not receive input + * events and do not participate in focus traversal. Overlay views + * are intended to be transient, such as might be needed by a temporary + * animation effect.</p> + * * <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 @@ -62,20 +56,20 @@ public interface Overlay { * @param view The View to be added to the overlay. The added view will be * drawn when the overlay is drawn. * @see #remove(View) - * @see #add(android.graphics.drawable.Drawable) + * @see ViewOverlay#add(Drawable) */ - void add(View view); + public void add(View view) { + mOverlayViewGroup.add(view); + } /** * Removes the specified View from the overlay. * * @param view The View to be removed from the overlay. * @see #add(View) + * @see ViewOverlay#remove(Drawable) */ - void remove(View view); - - /** - * Removes all views and drawables from the overlay. - */ - void clear(); + public void remove(View view) { + mOverlayViewGroup.remove(view); + } } diff --git a/core/java/android/view/ViewOverlay.java b/core/java/android/view/ViewOverlay.java index 8b18d53..78e2597 100644 --- a/core/java/android/view/ViewOverlay.java +++ b/core/java/android/view/ViewOverlay.java @@ -23,215 +23,286 @@ 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). + * 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 + * by adding and removing drawables. * - * 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. + * <p>An overlay requested from a ViewGroup is of type {@link ViewGroupOverlay}, + * which also supports adding and removing views.</p> * - * @hide + * @see View#getOverlay() View.getOverlay() + * @see ViewGroup#getOverlay() ViewGroup.getOverlay() + * @see ViewGroupOverlay */ -class ViewOverlay extends ViewGroup implements Overlay { +public class ViewOverlay { /** - * The View for which this is an overlay. Invalidations of the overlay are redirected to - * this host view. + * The actual container for the drawables (and views, if it's a ViewGroupOverlay). + * All of the management and rendering details for the overlay are handled in + * OverlayViewGroup. */ - View mHostView; + OverlayViewGroup mOverlayViewGroup; + + ViewOverlay(Context context, View hostView) { + mOverlayViewGroup = new OverlayViewGroup(context, hostView); + } /** - * The set of drawables to draw when the overlay is rendered. + * Used internally by View and ViewGroup to handle drawing and invalidation + * of the overlay + * @return */ - ArrayList<Drawable> mDrawables = null; - - ViewOverlay(Context context, View host) { - super(context); - mHostView = host; - mParent = mHostView.getParent(); + ViewGroup getOverlayView() { + return mOverlayViewGroup; } - @Override + /** + * Adds a Drawable to the overlay. The bounds of the drawable should be relative to + * the host view. Any drawable added to the overlay should be removed when it is no longer + * needed or no longer visible. + * + * @param drawable The Drawable to be added to the overlay. This drawable will be + * drawn when the view redraws its overlay. + * @see #remove(Drawable) + */ public void add(Drawable drawable) { - if (mDrawables == null) { - mDrawables = new ArrayList<Drawable>(); - } - if (!mDrawables.contains(drawable)) { - // Make each drawable unique in the overlay; can't add it more than once - mDrawables.add(drawable); - invalidate(drawable.getBounds()); - drawable.setCallback(this); - } + mOverlayViewGroup.add(drawable); } - @Override + /** + * Removes the specified Drawable from the overlay. + * + * @param drawable The Drawable to be removed from the overlay. + * @see #add(Drawable) + */ public void remove(Drawable drawable) { - if (mDrawables != null) { - mDrawables.remove(drawable); - invalidate(drawable.getBounds()); - drawable.setCallback(null); - } + mOverlayViewGroup.remove(drawable); } - @Override - public void invalidateDrawable(Drawable drawable) { - invalidate(drawable.getBounds()); + /** + * Removes all content from the overlay. + */ + public void clear() { + mOverlayViewGroup.clear(); } - @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]); + boolean isEmpty() { + return mOverlayViewGroup.isEmpty(); + } + + /** + * OverlayViewGroup is a container that View and ViewGroup use to host + * drawables and views added to their overlays ({@link ViewOverlay} and + * {@link ViewGroupOverlay}, respectively). Drawables are added to the overlay + * via the add/remove methods in ViewOverlay, Views are added/removed via + * ViewGroupOverlay. These drawable and view objects 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). + * + * <p>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.</p> + * + * @see View#getOverlay() + * @see ViewGroup#getOverlay() + */ + static class OverlayViewGroup extends ViewGroup { + + /** + * The View for which this is an overlay. Invalidations of the overlay are redirected to + * this host view. + */ + View mHostView; + + /** + * The set of drawables to draw when the overlay is rendered. + */ + ArrayList<Drawable> mDrawables = null; + + OverlayViewGroup(Context context, View hostView) { + super(context); + mHostView = hostView; + mAttachInfo = mHostView.mAttachInfo; + mRight = hostView.getWidth(); + mBottom = hostView.getHeight(); + } + + public void add(Drawable drawable) { + if (mDrawables == null) { + + mDrawables = new ArrayList<Drawable>(); + } + if (!mDrawables.contains(drawable)) { + // Make each drawable unique in the overlay; can't add it more than once + mDrawables.add(drawable); + invalidate(drawable.getBounds()); + drawable.setCallback(this); } - parent.removeView(child); } - super.addView(child); - } - @Override - public void remove(View view) { - super.removeView(view); - } + public void remove(Drawable drawable) { + if (mDrawables != null) { + mDrawables.remove(drawable); + invalidate(drawable.getBounds()); + drawable.setCallback(null); + } + } - @Override - public void clear() { - removeAllViews(); - mDrawables.clear(); - } + public void add(View child) { + 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); + } - boolean isEmpty() { - if (getChildCount() == 0 && (mDrawables == null || mDrawables.size() == 0)) { - return true; + public void remove(View view) { + super.removeView(view); } - return false; - } - @Override - protected void dispatchDraw(Canvas canvas) { - super.dispatchDraw(canvas); - final int numDrawables = (mDrawables == null) ? 0 : mDrawables.size(); - for (int i = 0; i < numDrawables; ++i) { - mDrawables.get(i).draw(canvas); + public void clear() { + removeAllViews(); + mDrawables.clear(); } - } - @Override - protected void onLayout(boolean changed, int l, int t, int r, int b) { - // Noop: children are positioned absolutely - } + boolean isEmpty() { + if (getChildCount() == 0 && + (mDrawables == null || mDrawables.size() == 0)) { + return true; + } + return false; + } - /* - The following invalidation overrides exist for the purpose of redirecting invalidation to - the host view. The overlay is not parented to the host view (since a View cannot be a parent), - so the invalidation cannot proceed through the normal parent hierarchy. - There is a built-in assumption that the overlay exactly covers the host view, therefore - the invalidation rectangles received do not need to be adjusted when forwarded to - the host view. - */ + @Override + public void invalidateDrawable(Drawable drawable) { + invalidate(drawable.getBounds()); + } - @Override - public void invalidate(Rect dirty) { - super.invalidate(dirty); - if (mHostView != null) { - mHostView.invalidate(dirty); + @Override + protected void dispatchDraw(Canvas canvas) { + super.dispatchDraw(canvas); + final int numDrawables = (mDrawables == null) ? 0 : mDrawables.size(); + for (int i = 0; i < numDrawables; ++i) { + mDrawables.get(i).draw(canvas); + } } - } - @Override - public void invalidate(int l, int t, int r, int b) { - super.invalidate(l, t, r, b); - if (mHostView != null) { - mHostView.invalidate(l, t, r, b); + @Override + protected void onLayout(boolean changed, int l, int t, int r, int b) { + // Noop: children are positioned absolutely } - } - @Override - public void invalidate() { - super.invalidate(); - if (mHostView != null) { - mHostView.invalidate(); + /* + The following invalidation overrides exist for the purpose of redirecting invalidation to + the host view. The overlay is not parented to the host view (since a View cannot be a + parent), so the invalidation cannot proceed through the normal parent hierarchy. + There is a built-in assumption that the overlay exactly covers the host view, therefore + the invalidation rectangles received do not need to be adjusted when forwarded to + the host view. + */ + + @Override + public void invalidate(Rect dirty) { + super.invalidate(dirty); + if (mHostView != null) { + mHostView.invalidate(dirty); + } } - } - @Override - void invalidate(boolean invalidateCache) { - super.invalidate(invalidateCache); - if (mHostView != null) { - mHostView.invalidate(invalidateCache); + @Override + public void invalidate(int l, int t, int r, int b) { + super.invalidate(l, t, r, b); + if (mHostView != null) { + mHostView.invalidate(l, t, r, b); + } } - } - @Override - void invalidateViewProperty(boolean invalidateParent, boolean forceRedraw) { - super.invalidateViewProperty(invalidateParent, forceRedraw); - if (mHostView != null) { - mHostView.invalidateViewProperty(invalidateParent, forceRedraw); + @Override + public void invalidate() { + super.invalidate(); + if (mHostView != null) { + mHostView.invalidate(); + } } - } - @Override - protected void invalidateParentCaches() { - super.invalidateParentCaches(); - if (mHostView != null) { - mHostView.invalidateParentCaches(); + @Override + void invalidate(boolean invalidateCache) { + super.invalidate(invalidateCache); + if (mHostView != null) { + mHostView.invalidate(invalidateCache); + } } - } - @Override - protected void invalidateParentIfNeeded() { - super.invalidateParentIfNeeded(); - if (mHostView != null) { - mHostView.invalidateParentIfNeeded(); + @Override + void invalidateViewProperty(boolean invalidateParent, boolean forceRedraw) { + super.invalidateViewProperty(invalidateParent, forceRedraw); + if (mHostView != null) { + mHostView.invalidateViewProperty(invalidateParent, forceRedraw); + } } - } - public void invalidateChildFast(View child, final Rect dirty) { - if (mHostView != null) { - // Note: This is not a "fast" invalidation. Would be nice to instead invalidate using DL - // properties and a dirty rect instead of causing a real invalidation of the host view - int left = child.mLeft; - int top = child.mTop; - if (!child.getMatrix().isIdentity()) { - child.transformRect(dirty); + @Override + protected void invalidateParentCaches() { + super.invalidateParentCaches(); + if (mHostView != null) { + mHostView.invalidateParentCaches(); + } + } + + @Override + protected void invalidateParentIfNeeded() { + super.invalidateParentIfNeeded(); + if (mHostView != null) { + mHostView.invalidateParentIfNeeded(); } - dirty.offset(left, top); - mHostView.invalidate(dirty); } - } - @Override - public ViewParent invalidateChildInParent(int[] location, Rect dirty) { - if (mHostView != null) { - 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); + public void invalidateChildFast(View child, final Rect dirty) { + if (mHostView != null) { + // Note: This is not a "fast" invalidation. Would be nice to instead invalidate + // using DisplayList properties and a dirty rect instead of causing a real + // invalidation of the host view + int left = child.mLeft; + int top = child.mTop; + if (!child.getMatrix().isIdentity()) { + child.transformRect(dirty); + } + dirty.offset(left, top); + mHostView.invalidate(dirty); } } - return null; + + @Override + public ViewParent invalidateChildInParent(int[] location, Rect dirty) { + if (mHostView != null) { + 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; + } } + } |