diff options
author | Alan Viverette <alanv@google.com> | 2014-05-16 20:29:08 +0000 |
---|---|---|
committer | Android (Google) Code Review <android-gerrit@google.com> | 2014-05-16 20:29:08 +0000 |
commit | 62cb534edb2cef23bdc71254294bd63fa03b38b3 (patch) | |
tree | b9587ba31898e4e98819482f6f038966c9c20c96 /core | |
parent | 779b59ced27c518479c466f45e6bc69ea295a5bf (diff) | |
parent | ad2f8e334f3ef22d3e412b0660a2e1f996f94116 (diff) | |
download | frameworks_base-62cb534edb2cef23bdc71254294bd63fa03b38b3.zip frameworks_base-62cb534edb2cef23bdc71254294bd63fa03b38b3.tar.gz frameworks_base-62cb534edb2cef23bdc71254294bd63fa03b38b3.tar.bz2 |
Merge "Update ripple behavior, use render thread animation"
Diffstat (limited to 'core')
-rw-r--r-- | core/java/android/view/RenderNodeAnimator.java | 140 | ||||
-rw-r--r-- | core/java/android/view/View.java | 35 | ||||
-rw-r--r-- | core/java/android/widget/Switch.java | 28 | ||||
-rw-r--r-- | core/java/com/android/internal/view/animation/FallbackLUTInterpolator.java | 6 | ||||
-rw-r--r-- | core/jni/android_view_RenderNodeAnimator.cpp | 23 |
5 files changed, 190 insertions, 42 deletions
diff --git a/core/java/android/view/RenderNodeAnimator.java b/core/java/android/view/RenderNodeAnimator.java index f14e73f..c1a4fee 100644 --- a/core/java/android/view/RenderNodeAnimator.java +++ b/core/java/android/view/RenderNodeAnimator.java @@ -16,6 +16,7 @@ package android.view; +import android.animation.Animator; import android.animation.TimeInterpolator; import android.graphics.Canvas; import android.graphics.CanvasProperty; @@ -28,12 +29,12 @@ import com.android.internal.view.animation.HasNativeInterpolator; import com.android.internal.view.animation.NativeInterpolatorFactory; import java.lang.ref.WeakReference; +import java.util.ArrayList; /** * @hide */ -public final class RenderNodeAnimator { - +public final class RenderNodeAnimator extends Animator { // Keep in sync with enum RenderProperty in Animator.h public static final int TRANSLATION_X = 0; public static final int TRANSLATION_Y = 1; @@ -50,6 +51,11 @@ public final class RenderNodeAnimator { // Keep in sync with enum PaintFields in Animator.h public static final int PAINT_STROKE_WIDTH = 0; + + /** + * Field for the Paint alpha channel, which should be specified as a value + * between 0 and 255. + */ public static final int PAINT_ALPHA = 1; // ViewPropertyAnimator uses a mask for its values, we need to remap them @@ -74,8 +80,11 @@ public final class RenderNodeAnimator { private VirtualRefBasePtr mNativePtr; private RenderNode mTarget; + private View mViewTarget; private TimeInterpolator mInterpolator; + private boolean mStarted = false; + private boolean mFinished = false; public int mapViewPropertyToRenderProperty(int viewProperty) { return sViewPropertyAnimatorMap.get(viewProperty); @@ -92,6 +101,14 @@ public final class RenderNodeAnimator { property.getNativeContainer(), finalValue)); } + /** + * Creates a new render node animator for a field on a Paint property. + * + * @param property The paint property to target + * @param paintField Paint field to animate, one of {@link #PAINT_ALPHA} or + * {@link #PAINT_STROKE_WIDTH} + * @param finalValue The target value for the property + */ public RenderNodeAnimator(CanvasProperty<Paint> property, int paintField, float finalValue) { init(nCreateCanvasPropertyPaintAnimator( new WeakReference<RenderNodeAnimator>(this), @@ -115,56 +132,139 @@ public final class RenderNodeAnimator { if (mInterpolator.getClass().isAnnotationPresent(HasNativeInterpolator.class)) { ni = ((NativeInterpolatorFactory)mInterpolator).createNativeInterpolator(); } else { - int duration = nGetDuration(mNativePtr.get()); + long duration = nGetDuration(mNativePtr.get()); ni = FallbackLUTInterpolator.createNativeInterpolator(mInterpolator, duration); } nSetInterpolator(mNativePtr.get(), ni); } - private void start(RenderNode node) { + @Override + public void start() { + if (mTarget == null) { + throw new IllegalStateException("Missing target!"); + } + if (mStarted) { throw new IllegalStateException("Already started!"); } + mStarted = true; applyInterpolator(); - mTarget = node; mTarget.addAnimator(this); + + final ArrayList<AnimatorListener> listeners = getListeners(); + final int numListeners = listeners == null ? 0 : listeners.size(); + for (int i = 0; i < numListeners; i++) { + listeners.get(i).onAnimationStart(this); + } + + if (mViewTarget != null) { + // Kick off a frame to start the process + mViewTarget.invalidateViewProperty(true, false); + } + } + + @Override + public void cancel() { + mTarget.removeAnimator(this); + + final ArrayList<AnimatorListener> listeners = getListeners(); + final int numListeners = listeners == null ? 0 : listeners.size(); + for (int i = 0; i < numListeners; i++) { + listeners.get(i).onAnimationCancel(this); + } + } + + @Override + public void end() { + throw new UnsupportedOperationException(); + } + + @Override + public void pause() { + throw new UnsupportedOperationException(); + } + + @Override + public void resume() { + throw new UnsupportedOperationException(); } - public void start(View target) { - start(target.mRenderNode); - // Kick off a frame to start the process - target.invalidateViewProperty(true, false); + public void setTarget(View view) { + mViewTarget = view; + mTarget = view.mRenderNode; } - public void start(Canvas canvas) { + public void setTarget(Canvas canvas) { if (!(canvas instanceof GLES20RecordingCanvas)) { throw new IllegalArgumentException("Not a GLES20RecordingCanvas"); } - GLES20RecordingCanvas recordingCanvas = (GLES20RecordingCanvas) canvas; - start(recordingCanvas.mNode); + + final GLES20RecordingCanvas recordingCanvas = (GLES20RecordingCanvas) canvas; + setTarget(recordingCanvas.mNode); } - public void cancel() { - mTarget.removeAnimator(this); + public void setTarget(RenderNode node) { + mViewTarget = null; + mTarget = node; + } + + public RenderNode getTarget() { + return mTarget; } - public void setDuration(int duration) { + @Override + public void setStartDelay(long startDelay) { + checkMutable(); + nSetStartDelay(mNativePtr.get(), startDelay); + } + + @Override + public long getStartDelay() { + return nGetStartDelay(mNativePtr.get()); + } + + @Override + public RenderNodeAnimator setDuration(long duration) { checkMutable(); nSetDuration(mNativePtr.get(), duration); + return this; } + @Override + public long getDuration() { + return nGetDuration(mNativePtr.get()); + } + + @Override + public boolean isRunning() { + return mStarted && !mFinished; + } + + @Override public void setInterpolator(TimeInterpolator interpolator) { checkMutable(); mInterpolator = interpolator; } - long getNativeAnimator() { - return mNativePtr.get(); + @Override + public TimeInterpolator getInterpolator() { + return mInterpolator; } private void onFinished() { + mFinished = true; mTarget.removeAnimator(this); + + final ArrayList<AnimatorListener> listeners = getListeners(); + final int numListeners = listeners == null ? 0 : listeners.size(); + for (int i = 0; i < numListeners; i++) { + listeners.get(i).onAnimationEnd(this); + } + } + + long getNativeAnimator() { + return mNativePtr.get(); } // Called by native @@ -181,7 +281,9 @@ public final class RenderNodeAnimator { long canvasProperty, float deltaValue); private static native long nCreateCanvasPropertyPaintAnimator(WeakReference<RenderNodeAnimator> weakThis, long canvasProperty, int paintField, float deltaValue); - private static native void nSetDuration(long nativePtr, int duration); - private static native int nGetDuration(long nativePtr); + private static native void nSetDuration(long nativePtr, long duration); + private static native long nGetDuration(long nativePtr); + private static native void nSetStartDelay(long nativePtr, long startDelay); + private static native long nGetStartDelay(long nativePtr); private static native void nSetInterpolator(long animPtr, long interpolatorPtr); } diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java index 5141877..fb7d57d 100644 --- a/core/java/android/view/View.java +++ b/core/java/android/view/View.java @@ -4774,8 +4774,8 @@ public class View implements Drawable.Callback, KeyEvent.Callback, mAttachInfo.mTreeObserver.dispatchOnGlobalFocusChange(oldFocus, this); } - manageFocusHotspot(true, oldFocus); onFocusChanged(true, direction, previouslyFocusedRect); + manageFocusHotspot(true, oldFocus); refreshDrawableState(); } } @@ -6752,6 +6752,24 @@ public class View implements Drawable.Callback, KeyEvent.Callback, } /** + * Sets the pressed state for this view and provides a touch coordinate for + * animation hinting. + * + * @param pressed Pass true to set the View's internal state to "pressed", + * or false to reverts the View's internal state from a + * previously set "pressed" state. + * @param x The x coordinate of the touch that caused the press + * @param y The y coordinate of the touch that caused the press + */ + private void setPressed(boolean pressed, float x, float y) { + if (pressed) { + setHotspot(R.attr.state_pressed, x, y); + } + + setPressed(pressed); + } + + /** * Sets the pressed state for this view. * * @see #isClickable() @@ -6769,6 +6787,10 @@ public class View implements Drawable.Callback, KeyEvent.Callback, mPrivateFlags &= ~PFLAG_PRESSED; } + if (!pressed) { + clearHotspot(R.attr.state_pressed); + } + if (needsRefresh) { refreshDrawableState(); } @@ -8993,7 +9015,6 @@ public class View implements Drawable.Callback, KeyEvent.Callback, if ((viewFlags & ENABLED_MASK) == DISABLED) { if (event.getAction() == MotionEvent.ACTION_UP && (mPrivateFlags & PFLAG_PRESSED) != 0) { - clearHotspot(R.attr.state_pressed); setPressed(false); } // A disabled view that is clickable still consumes the touch @@ -9026,8 +9047,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, // showed it as pressed. Make it show the pressed // state now (before scheduling the click) to ensure // the user sees it. - setHotspot(R.attr.state_pressed, x, y); - setPressed(true); + setPressed(true, x, y); } if (!mHasPerformedLongPress) { @@ -9061,8 +9081,6 @@ public class View implements Drawable.Callback, KeyEvent.Callback, } removeTapCallback(); - } else { - clearHotspot(R.attr.state_pressed); } break; @@ -9175,7 +9193,6 @@ public class View implements Drawable.Callback, KeyEvent.Callback, */ private void removeUnsetPressCallback() { if ((mPrivateFlags & PFLAG_PRESSED) != 0 && mUnsetPressedState != null) { - clearHotspot(R.attr.state_pressed); setPressed(false); removeCallbacks(mUnsetPressedState); } @@ -19234,8 +19251,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, @Override public void run() { mPrivateFlags &= ~PFLAG_PREPRESSED; - setHotspot(R.attr.state_pressed, x, y); - setPressed(true); + setPressed(true, x, y); checkForLongClick(ViewConfiguration.getTapTimeout()); } } @@ -19516,7 +19532,6 @@ public class View implements Drawable.Callback, KeyEvent.Callback, private final class UnsetPressedState implements Runnable { @Override public void run() { - clearHotspot(R.attr.state_pressed); setPressed(false); } } diff --git a/core/java/android/widget/Switch.java b/core/java/android/widget/Switch.java index 438e164..74a3eec 100644 --- a/core/java/android/widget/Switch.java +++ b/core/java/android/widget/Switch.java @@ -666,6 +666,8 @@ public class Switch extends CompoundButton { case MotionEvent.ACTION_CANCEL: { if (mTouchMode == TOUCH_MODE_DRAGGING) { stopDrag(ev); + // Allow super class to handle pressed state, etc. + super.onTouchEvent(ev); return true; } mTouchMode = TOUCH_MODE_IDLE; @@ -801,7 +803,7 @@ public class Switch extends CompoundButton { } @Override - protected void onDraw(Canvas canvas) { + public void draw(Canvas c) { final Rect tempRect = mTempRect; final Drawable trackDrawable = mTrackDrawable; final Drawable thumbDrawable = mThumbDrawable; @@ -815,9 +817,6 @@ public class Switch extends CompoundButton { trackDrawable.getPadding(tempRect); final int switchInnerLeft = switchLeft + tempRect.left; - final int switchInnerTop = switchTop + tempRect.top; - final int switchInnerRight = switchRight - tempRect.right; - final int switchInnerBottom = switchBottom - tempRect.bottom; // Relies on mTempRect, MUST be called first! final int thumbPos = getThumbOffset(); @@ -833,8 +832,26 @@ public class Switch extends CompoundButton { background.setHotspotBounds(thumbLeft, switchTop, thumbRight, switchBottom); } + // Draw the background. + super.draw(c); + } + + @Override + protected void onDraw(Canvas canvas) { super.onDraw(canvas); + final Rect tempRect = mTempRect; + final Drawable trackDrawable = mTrackDrawable; + final Drawable thumbDrawable = mThumbDrawable; + trackDrawable.getPadding(tempRect); + + final int switchTop = mSwitchTop; + final int switchBottom = mSwitchBottom; + final int switchInnerLeft = mSwitchLeft + tempRect.left; + final int switchInnerTop = switchTop + tempRect.top; + final int switchInnerRight = mSwitchRight - tempRect.right; + final int switchInnerBottom = switchBottom - tempRect.bottom; + if (mSplitTrack) { final Insets insets = thumbDrawable.getOpticalInsets(); thumbDrawable.copyBounds(tempRect); @@ -861,7 +878,8 @@ public class Switch extends CompoundButton { } mTextPaint.drawableState = drawableState; - final int left = (thumbLeft + thumbRight) / 2 - switchText.getWidth() / 2; + final Rect thumbBounds = thumbDrawable.getBounds(); + final int left = (thumbBounds.left + thumbBounds.right) / 2 - switchText.getWidth() / 2; final int top = (switchInnerTop + switchInnerBottom) / 2 - switchText.getHeight() / 2; canvas.translate(left, top); switchText.draw(canvas); diff --git a/core/java/com/android/internal/view/animation/FallbackLUTInterpolator.java b/core/java/com/android/internal/view/animation/FallbackLUTInterpolator.java index aec2b7e..1feb943 100644 --- a/core/java/com/android/internal/view/animation/FallbackLUTInterpolator.java +++ b/core/java/com/android/internal/view/animation/FallbackLUTInterpolator.java @@ -34,11 +34,11 @@ public class FallbackLUTInterpolator implements NativeInterpolatorFactory { * Used to cache the float[] LUT for use across multiple native * interpolator creation */ - public FallbackLUTInterpolator(TimeInterpolator interpolator, int duration) { + public FallbackLUTInterpolator(TimeInterpolator interpolator, long duration) { mLut = createLUT(interpolator, duration); } - private static float[] createLUT(TimeInterpolator interpolator, int duration) { + private static float[] createLUT(TimeInterpolator interpolator, long duration) { long frameIntervalNanos = Choreographer.getInstance().getFrameIntervalNanos(); int animIntervalMs = (int) (frameIntervalNanos / TimeUtils.NANOS_PER_MS); int numAnimFrames = (int) Math.ceil(duration / animIntervalMs); @@ -59,7 +59,7 @@ public class FallbackLUTInterpolator implements NativeInterpolatorFactory { /** * Used to create a one-shot float[] LUT & native interpolator */ - public static long createNativeInterpolator(TimeInterpolator interpolator, int duration) { + public static long createNativeInterpolator(TimeInterpolator interpolator, long duration) { float[] lut = createLUT(interpolator, duration); return NativeInterpolatorFactoryHelper.createLutInterpolator(lut); } diff --git a/core/jni/android_view_RenderNodeAnimator.cpp b/core/jni/android_view_RenderNodeAnimator.cpp index ea2f96e..e19ce36 100644 --- a/core/jni/android_view_RenderNodeAnimator.cpp +++ b/core/jni/android_view_RenderNodeAnimator.cpp @@ -116,15 +116,26 @@ static jlong createCanvasPropertyPaintAnimator(JNIEnv* env, jobject clazz, return reinterpret_cast<jlong>( animator ); } -static void setDuration(JNIEnv* env, jobject clazz, jlong animatorPtr, jint duration) { +static void setDuration(JNIEnv* env, jobject clazz, jlong animatorPtr, jlong duration) { LOG_ALWAYS_FATAL_IF(duration < 0, "Duration cannot be negative"); BaseRenderNodeAnimator* animator = reinterpret_cast<BaseRenderNodeAnimator*>(animatorPtr); animator->setDuration(duration); } -static jint getDuration(JNIEnv* env, jobject clazz, jlong animatorPtr) { +static jlong getDuration(JNIEnv* env, jobject clazz, jlong animatorPtr) { BaseRenderNodeAnimator* animator = reinterpret_cast<BaseRenderNodeAnimator*>(animatorPtr); - return static_cast<jint>(animator->duration()); + return static_cast<jlong>(animator->duration()); +} + +static void setStartDelay(JNIEnv* env, jobject clazz, jlong animatorPtr, jlong startDelay) { + LOG_ALWAYS_FATAL_IF(startDelay < 0, "Start delay cannot be negative"); + BaseRenderNodeAnimator* animator = reinterpret_cast<BaseRenderNodeAnimator*>(animatorPtr); + animator->setStartDelay(startDelay); +} + +static jlong getStartDelay(JNIEnv* env, jobject clazz, jlong animatorPtr) { + BaseRenderNodeAnimator* animator = reinterpret_cast<BaseRenderNodeAnimator*>(animatorPtr); + return static_cast<jlong>(animator->startDelay()); } static void setInterpolator(JNIEnv* env, jobject clazz, jlong animatorPtr, jlong interpolatorPtr) { @@ -146,8 +157,10 @@ static JNINativeMethod gMethods[] = { { "nCreateAnimator", "(Ljava/lang/ref/WeakReference;IF)J", (void*) createAnimator }, { "nCreateCanvasPropertyFloatAnimator", "(Ljava/lang/ref/WeakReference;JF)J", (void*) createCanvasPropertyFloatAnimator }, { "nCreateCanvasPropertyPaintAnimator", "(Ljava/lang/ref/WeakReference;JIF)J", (void*) createCanvasPropertyPaintAnimator }, - { "nSetDuration", "(JI)V", (void*) setDuration }, - { "nGetDuration", "(J)I", (void*) getDuration }, + { "nSetDuration", "(JJ)V", (void*) setDuration }, + { "nGetDuration", "(J)J", (void*) getDuration }, + { "nSetStartDelay", "(JJ)V", (void*) setStartDelay }, + { "nGetStartDelay", "(J)J", (void*) getStartDelay }, { "nSetInterpolator", "(JJ)V", (void*) setInterpolator }, #endif }; |