summaryrefslogtreecommitdiffstats
path: root/core
diff options
context:
space:
mode:
authorAlan Viverette <alanv@google.com>2014-05-16 20:29:08 +0000
committerAndroid (Google) Code Review <android-gerrit@google.com>2014-05-16 20:29:08 +0000
commit62cb534edb2cef23bdc71254294bd63fa03b38b3 (patch)
treeb9587ba31898e4e98819482f6f038966c9c20c96 /core
parent779b59ced27c518479c466f45e6bc69ea295a5bf (diff)
parentad2f8e334f3ef22d3e412b0660a2e1f996f94116 (diff)
downloadframeworks_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.java140
-rw-r--r--core/java/android/view/View.java35
-rw-r--r--core/java/android/widget/Switch.java28
-rw-r--r--core/java/com/android/internal/view/animation/FallbackLUTInterpolator.java6
-rw-r--r--core/jni/android_view_RenderNodeAnimator.cpp23
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
};