diff options
author | Romain Guy <romainguy@google.com> | 2012-05-23 16:08:53 -0700 |
---|---|---|
committer | Android Git Automerger <android-git-automerger@android.com> | 2012-05-23 16:08:53 -0700 |
commit | 425f126a0f2284423f4ccea0b00fbd5ea670a6c9 (patch) | |
tree | cfe6851e3803c68895f0ed0c14974ce9f6217b03 /core | |
parent | 762932396aecab31a89f64399df9d44cc177e3df (diff) | |
parent | a865d7d7d3612d99e3b1407793610056c7df163c (diff) | |
download | frameworks_base-425f126a0f2284423f4ccea0b00fbd5ea670a6c9.zip frameworks_base-425f126a0f2284423f4ccea0b00fbd5ea670a6c9.tar.gz frameworks_base-425f126a0f2284423f4ccea0b00fbd5ea670a6c9.tar.bz2 |
am a865d7d7: am df3633b3: Merge "Make it harder for apps to mess up ViewGroup\'s internal state Bug #6421288" into jb-dev
* commit 'a865d7d7d3612d99e3b1407793610056c7df163c':
Make it harder for apps to mess up ViewGroup's internal state Bug #6421288
Diffstat (limited to 'core')
-rw-r--r-- | core/java/android/view/View.java | 2 | ||||
-rw-r--r-- | core/java/android/view/ViewGroup.java | 52 | ||||
-rw-r--r-- | core/java/android/view/animation/Animation.java | 79 |
3 files changed, 118 insertions, 15 deletions
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java index 483560c..706ad59 100644 --- a/core/java/android/view/View.java +++ b/core/java/android/view/View.java @@ -12697,6 +12697,7 @@ public class View implements Drawable.Callback, Drawable.Callback2, KeyEvent.Cal if (!initialized) { a.initialize(mRight - mLeft, mBottom - mTop, parent.getWidth(), parent.getHeight()); a.initializeInvalidateRegion(0, 0, mRight - mLeft, mBottom - mTop); + if (mAttachInfo != null) a.setListenerHandler(mAttachInfo.mHandler); onAnimationStart(); } @@ -12710,6 +12711,7 @@ public class View implements Drawable.Callback, Drawable.Callback2, KeyEvent.Cal } else { invalidationTransform = parent.mChildTransformation; } + if (more) { if (!a.willChangeBounds()) { if ((flags & (parent.FLAG_OPTIMIZE_INVALIDATE | parent.FLAG_ANIMATION_DONE)) == diff --git a/core/java/android/view/ViewGroup.java b/core/java/android/view/ViewGroup.java index ab42d57..1aec7c8 100644 --- a/core/java/android/view/ViewGroup.java +++ b/core/java/android/view/ViewGroup.java @@ -3154,8 +3154,12 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager } /** - * Adds a child view. If no layout parameters are already set on the child, the - * default parameters for this ViewGroup are set on the child. + * <p>Adds a child view. If no layout parameters are already set on the child, the + * default parameters for this ViewGroup are set on the child.</p> + * + * <p><strong>Note:</strong> do not invoke this method from + * {@link #draw(android.graphics.Canvas)}, {@link #onDraw(android.graphics.Canvas)}, + * {@link #dispatchDraw(android.graphics.Canvas)} or any related method.</p> * * @param child the child view to add * @@ -3168,6 +3172,10 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager /** * Adds a child view. If no layout parameters are already set on the child, the * default parameters for this ViewGroup are set on the child. + * + * <p><strong>Note:</strong> do not invoke this method from + * {@link #draw(android.graphics.Canvas)}, {@link #onDraw(android.graphics.Canvas)}, + * {@link #dispatchDraw(android.graphics.Canvas)} or any related method.</p> * * @param child the child view to add * @param index the position at which to add the child @@ -3189,6 +3197,10 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager * Adds a child view with this ViewGroup's default layout parameters and the * specified width and height. * + * <p><strong>Note:</strong> do not invoke this method from + * {@link #draw(android.graphics.Canvas)}, {@link #onDraw(android.graphics.Canvas)}, + * {@link #dispatchDraw(android.graphics.Canvas)} or any related method.</p> + * * @param child the child view to add */ public void addView(View child, int width, int height) { @@ -3201,6 +3213,10 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager /** * Adds a child view with the specified layout parameters. * + * <p><strong>Note:</strong> do not invoke this method from + * {@link #draw(android.graphics.Canvas)}, {@link #onDraw(android.graphics.Canvas)}, + * {@link #dispatchDraw(android.graphics.Canvas)} or any related method.</p> + * * @param child the child view to add * @param params the layout parameters to set on the child */ @@ -3211,6 +3227,10 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager /** * Adds a child view with the specified layout parameters. * + * <p><strong>Note:</strong> do not invoke this method from + * {@link #draw(android.graphics.Canvas)}, {@link #onDraw(android.graphics.Canvas)}, + * {@link #dispatchDraw(android.graphics.Canvas)} or any related method.</p> + * * @param child the child view to add * @param index the position at which to add the child * @param params the layout parameters to set on the child @@ -3528,6 +3548,10 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager /** * {@inheritDoc} + * + * <p><strong>Note:</strong> do not invoke this method from + * {@link #draw(android.graphics.Canvas)}, {@link #onDraw(android.graphics.Canvas)}, + * {@link #dispatchDraw(android.graphics.Canvas)} or any related method.</p> */ public void removeView(View view) { removeViewInternal(view); @@ -3539,6 +3563,10 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager * Removes a view during layout. This is useful if in your onLayout() method, * you need to remove more views. * + * <p><strong>Note:</strong> do not invoke this method from + * {@link #draw(android.graphics.Canvas)}, {@link #onDraw(android.graphics.Canvas)}, + * {@link #dispatchDraw(android.graphics.Canvas)} or any related method.</p> + * * @param view the view to remove from the group */ public void removeViewInLayout(View view) { @@ -3549,6 +3577,10 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager * Removes a range of views during layout. This is useful if in your onLayout() method, * you need to remove more views. * + * <p><strong>Note:</strong> do not invoke this method from + * {@link #draw(android.graphics.Canvas)}, {@link #onDraw(android.graphics.Canvas)}, + * {@link #dispatchDraw(android.graphics.Canvas)} or any related method.</p> + * * @param start the index of the first view to remove from the group * @param count the number of views to remove from the group */ @@ -3559,6 +3591,10 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager /** * Removes the view at the specified position in the group. * + * <p><strong>Note:</strong> do not invoke this method from + * {@link #draw(android.graphics.Canvas)}, {@link #onDraw(android.graphics.Canvas)}, + * {@link #dispatchDraw(android.graphics.Canvas)} or any related method.</p> + * * @param index the position in the group of the view to remove */ public void removeViewAt(int index) { @@ -3570,6 +3606,10 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager /** * Removes the specified range of views from the group. * + * <p><strong>Note:</strong> do not invoke this method from + * {@link #draw(android.graphics.Canvas)}, {@link #onDraw(android.graphics.Canvas)}, + * {@link #dispatchDraw(android.graphics.Canvas)} or any related method.</p> + * * @param start the first position in the group of the range of views to remove * @param count the number of views to remove */ @@ -3715,6 +3755,10 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager /** * Call this method to remove all child views from the * ViewGroup. + * + * <p><strong>Note:</strong> do not invoke this method from + * {@link #draw(android.graphics.Canvas)}, {@link #onDraw(android.graphics.Canvas)}, + * {@link #dispatchDraw(android.graphics.Canvas)} or any related method.</p> */ public void removeAllViews() { removeAllViewsInLayout(); @@ -3730,6 +3774,10 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager * that can currently fit inside the object on screen. Do not call * this method unless you are extending ViewGroup and understand the * view measuring and layout pipeline. + * + * <p><strong>Note:</strong> do not invoke this method from + * {@link #draw(android.graphics.Canvas)}, {@link #onDraw(android.graphics.Canvas)}, + * {@link #dispatchDraw(android.graphics.Canvas)} or any related method.</p> */ public void removeAllViewsInLayout() { final int count = mChildrenCount; diff --git a/core/java/android/view/animation/Animation.java b/core/java/android/view/animation/Animation.java index d92ebcd..85d77cb 100644 --- a/core/java/android/view/animation/Animation.java +++ b/core/java/android/view/animation/Animation.java @@ -19,6 +19,7 @@ package android.view.animation; import android.content.Context; import android.content.res.TypedArray; import android.graphics.RectF; +import android.os.Handler; import android.os.SystemProperties; import android.util.AttributeSet; import android.util.TypedValue; @@ -207,6 +208,11 @@ public abstract class Animation implements Cloneable { private final CloseGuard guard = CloseGuard.get(); + private Handler mListenerHandler; + private Runnable mOnStart; + private Runnable mOnRepeat; + private Runnable mOnEnd; + /** * Creates a new animation with a duration of 0ms, the default interpolator, with * fillBefore set to true and fillAfter set to false @@ -275,6 +281,7 @@ public abstract class Animation implements Cloneable { mRepeated = 0; mMore = true; mOneMoreTime = true; + mListenerHandler = null; } /** @@ -290,7 +297,7 @@ public abstract class Animation implements Cloneable { */ public void cancel() { if (mStarted && !mEnded) { - if (mListener != null) mListener.onAnimationEnd(this); + fireAnimationEnd(); mEnded = true; guard.close(); } @@ -306,7 +313,7 @@ public abstract class Animation implements Cloneable { if (mStarted && !mEnded) { mEnded = true; guard.close(); - if (mListener != null) mListener.onAnimationEnd(this); + fireAnimationEnd(); } } @@ -341,6 +348,38 @@ public abstract class Animation implements Cloneable { } /** + * Sets the handler used to invoke listeners. + * + * @hide + */ + public void setListenerHandler(Handler handler) { + if (mListenerHandler == null) { + mOnStart = new Runnable() { + public void run() { + if (mListener != null) { + mListener.onAnimationStart(Animation.this); + } + } + }; + mOnRepeat = new Runnable() { + public void run() { + if (mListener != null) { + mListener.onAnimationRepeat(Animation.this); + } + } + }; + mOnEnd = new Runnable() { + public void run() { + if (mListener != null) { + mListener.onAnimationEnd(Animation.this); + } + } + }; + } + mListenerHandler = handler; + } + + /** * Sets the acceleration curve for this animation. The interpolator is loaded as * a resource from the specified context. * @@ -792,7 +831,6 @@ public abstract class Animation implements Cloneable { * @return True if the animation is still running */ public boolean getTransformation(long currentTime, Transformation outTransformation) { - if (mStartTime == -1) { mStartTime = currentTime; } @@ -815,9 +853,7 @@ public abstract class Animation implements Cloneable { if ((normalizedTime >= 0.0f || mFillBefore) && (normalizedTime <= 1.0f || mFillAfter)) { if (!mStarted) { - if (mListener != null) { - mListener.onAnimationStart(this); - } + fireAnimationStart(); mStarted = true; if (USE_CLOSEGUARD) { guard.open("cancel or detach or getTransformation"); @@ -839,9 +875,7 @@ public abstract class Animation implements Cloneable { if (!mEnded) { mEnded = true; guard.close(); - if (mListener != null) { - mListener.onAnimationEnd(this); - } + fireAnimationEnd(); } } else { if (mRepeatCount > 0) { @@ -855,9 +889,7 @@ public abstract class Animation implements Cloneable { mStartTime = -1; mMore = true; - if (mListener != null) { - mListener.onAnimationRepeat(this); - } + fireAnimationRepeat(); } } @@ -868,7 +900,28 @@ public abstract class Animation implements Cloneable { return mMore; } - + + private void fireAnimationStart() { + if (mListener != null) { + if (mListenerHandler == null) mListener.onAnimationStart(this); + else mListenerHandler.postAtFrontOfQueue(mOnStart); + } + } + + private void fireAnimationRepeat() { + if (mListener != null) { + if (mListenerHandler == null) mListener.onAnimationRepeat(this); + else mListenerHandler.postAtFrontOfQueue(mOnRepeat); + } + } + + private void fireAnimationEnd() { + if (mListener != null) { + if (mListenerHandler == null) mListener.onAnimationEnd(this); + else mListenerHandler.postAtFrontOfQueue(mOnEnd); + } + } + /** * Gets the transformation to apply at a specified point in time. Implementations of this * method should always replace the specified Transformation or document they are doing |