Merge "Baby steps"
This commit is contained in:
@@ -48,6 +48,8 @@ public final class RenderNodeAnimator extends Animator {
|
||||
public static final int Y = 9;
|
||||
public static final int Z = 10;
|
||||
public static final int ALPHA = 11;
|
||||
// The last value in the enum, used for array size initialization
|
||||
public static final int LAST_VALUE = ALPHA;
|
||||
|
||||
// Keep in sync with enum PaintFields in Animator.h
|
||||
public static final int PAINT_STROKE_WIDTH = 0;
|
||||
@@ -86,7 +88,7 @@ public final class RenderNodeAnimator extends Animator {
|
||||
private boolean mStarted = false;
|
||||
private boolean mFinished = false;
|
||||
|
||||
public int mapViewPropertyToRenderProperty(int viewProperty) {
|
||||
public static int mapViewPropertyToRenderProperty(int viewProperty) {
|
||||
return sViewPropertyAnimatorMap.get(viewProperty);
|
||||
}
|
||||
|
||||
@@ -125,11 +127,15 @@ public final class RenderNodeAnimator extends Animator {
|
||||
}
|
||||
}
|
||||
|
||||
static boolean isNativeInterpolator(TimeInterpolator interpolator) {
|
||||
return interpolator.getClass().isAnnotationPresent(HasNativeInterpolator.class);
|
||||
}
|
||||
|
||||
private void applyInterpolator() {
|
||||
if (mInterpolator == null) return;
|
||||
|
||||
long ni;
|
||||
if (mInterpolator.getClass().isAnnotationPresent(HasNativeInterpolator.class)) {
|
||||
if (isNativeInterpolator(mInterpolator)) {
|
||||
ni = ((NativeInterpolatorFactory)mInterpolator).createNativeInterpolator();
|
||||
} else {
|
||||
long duration = nGetDuration(mNativePtr.get());
|
||||
|
||||
@@ -19,6 +19,7 @@ package android.view;
|
||||
import android.animation.Animator;
|
||||
import android.animation.ValueAnimator;
|
||||
import android.animation.TimeInterpolator;
|
||||
import android.os.Build;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
@@ -108,6 +109,11 @@ public class ViewPropertyAnimator {
|
||||
*/
|
||||
private ValueAnimator mTempValueAnimator;
|
||||
|
||||
/**
|
||||
* A RenderThread-driven backend that may intercept startAnimation
|
||||
*/
|
||||
private ViewPropertyAnimatorRT mRTBackend;
|
||||
|
||||
/**
|
||||
* This listener is the mechanism by which the underlying Animator causes changes to the
|
||||
* properties currently being animated, as well as the cleanup after an animation is
|
||||
@@ -227,7 +233,7 @@ public class ViewPropertyAnimator {
|
||||
* values are used to calculate the animated value for a given animation fraction
|
||||
* during the animation.
|
||||
*/
|
||||
private static class NameValuesHolder {
|
||||
static class NameValuesHolder {
|
||||
int mNameConstant;
|
||||
float mFromValue;
|
||||
float mDeltaValue;
|
||||
@@ -247,6 +253,9 @@ public class ViewPropertyAnimator {
|
||||
ViewPropertyAnimator(View view) {
|
||||
mView = view;
|
||||
view.ensureTransformationInfo();
|
||||
if (view.getContext().getApplicationInfo().targetSdkVersion >= Build.VERSION_CODES.L) {
|
||||
mRTBackend = new ViewPropertyAnimatorRT(view);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -371,6 +380,10 @@ public class ViewPropertyAnimator {
|
||||
return this;
|
||||
}
|
||||
|
||||
Animator.AnimatorListener getListener() {
|
||||
return mListener;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a listener for update events in the underlying ValueAnimator that runs
|
||||
* the property animations. Note that the underlying animator is animating between
|
||||
@@ -390,6 +403,10 @@ public class ViewPropertyAnimator {
|
||||
return this;
|
||||
}
|
||||
|
||||
ValueAnimator.AnimatorUpdateListener getUpdateListener() {
|
||||
return mUpdateListener;
|
||||
}
|
||||
|
||||
/**
|
||||
* Starts the currently pending property animations immediately. Calling <code>start()</code>
|
||||
* is optional because all animations start automatically at the next opportunity. However,
|
||||
@@ -825,12 +842,22 @@ public class ViewPropertyAnimator {
|
||||
return this;
|
||||
}
|
||||
|
||||
boolean hasActions() {
|
||||
return mPendingSetupAction != null
|
||||
|| mPendingCleanupAction != null
|
||||
|| mPendingOnStartAction != null
|
||||
|| mPendingOnEndAction != null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Starts the underlying Animator for a set of properties. We use a single animator that
|
||||
* simply runs from 0 to 1, and then use that fractional value to set each property
|
||||
* value accordingly.
|
||||
*/
|
||||
private void startAnimation() {
|
||||
if (mRTBackend != null && mRTBackend.startAnimation(this)) {
|
||||
return;
|
||||
}
|
||||
mView.setHasTransientState(true);
|
||||
ValueAnimator animator = ValueAnimator.ofFloat(1.0f);
|
||||
ArrayList<NameValuesHolder> nameValueList =
|
||||
|
||||
118
core/java/android/view/ViewPropertyAnimatorRT.java
Normal file
118
core/java/android/view/ViewPropertyAnimatorRT.java
Normal file
@@ -0,0 +1,118 @@
|
||||
/*
|
||||
* Copyright (C) 2014 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package android.view;
|
||||
|
||||
import android.animation.TimeInterpolator;
|
||||
import android.view.ViewPropertyAnimator.NameValuesHolder;
|
||||
|
||||
import com.android.internal.view.animation.FallbackLUTInterpolator;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
|
||||
/**
|
||||
* This is a RenderThread driven backend for ViewPropertyAnimator.
|
||||
*/
|
||||
class ViewPropertyAnimatorRT {
|
||||
|
||||
private final View mView;
|
||||
|
||||
private RenderNodeAnimator mAnimators[] = new RenderNodeAnimator[RenderNodeAnimator.LAST_VALUE + 1];
|
||||
|
||||
ViewPropertyAnimatorRT(View view) {
|
||||
mView = view;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return true if ViewPropertyAnimatorRT handled the animation,
|
||||
* false if ViewPropertyAnimator needs to handle it
|
||||
*/
|
||||
public boolean startAnimation(ViewPropertyAnimator parent) {
|
||||
cancelAnimators(parent.mPendingAnimations);
|
||||
if (!canHandleAnimator(parent)) {
|
||||
return false;
|
||||
}
|
||||
doStartAnimation(parent);
|
||||
return true;
|
||||
}
|
||||
|
||||
private void doStartAnimation(ViewPropertyAnimator parent) {
|
||||
int size = parent.mPendingAnimations.size();
|
||||
|
||||
long startDelay = parent.getStartDelay();
|
||||
long duration = parent.getDuration();
|
||||
TimeInterpolator interpolator = parent.getInterpolator();
|
||||
if (!RenderNodeAnimator.isNativeInterpolator(interpolator)) {
|
||||
interpolator = new FallbackLUTInterpolator(interpolator, duration);
|
||||
}
|
||||
for (int i = 0; i < size; i++) {
|
||||
NameValuesHolder holder = parent.mPendingAnimations.get(i);
|
||||
int property = RenderNodeAnimator.mapViewPropertyToRenderProperty(holder.mNameConstant);
|
||||
|
||||
RenderNodeAnimator animator = new RenderNodeAnimator(property, holder.mFromValue + holder.mDeltaValue);
|
||||
animator.setStartDelay(startDelay);
|
||||
animator.setDuration(duration);
|
||||
animator.setInterpolator(interpolator);
|
||||
animator.setTarget(mView);
|
||||
animator.start();
|
||||
}
|
||||
|
||||
parent.mPendingAnimations.clear();
|
||||
}
|
||||
|
||||
private boolean canHandleAnimator(ViewPropertyAnimator parent) {
|
||||
// TODO: Can we eliminate this entirely?
|
||||
// If RenderNode.animatorProperties() can be toggled to point at staging
|
||||
// instead then RNA can be used as the animators for software as well
|
||||
// as the updateListener fallback paths. If this can be toggled
|
||||
// at the top level somehow, combined with requiresUiRedraw, we could
|
||||
// ensure that RT does not self-animate, allowing for safe driving of
|
||||
// the animators from the UI thread using the same mechanisms
|
||||
// ViewPropertyAnimator does, just with everything sitting on a single
|
||||
// animator subsystem instead of multiple.
|
||||
|
||||
if (parent.getUpdateListener() != null) {
|
||||
return false;
|
||||
}
|
||||
if (parent.getListener() != null) {
|
||||
// TODO support
|
||||
return false;
|
||||
}
|
||||
if (!mView.isHardwareAccelerated()) {
|
||||
// TODO handle this maybe?
|
||||
return false;
|
||||
}
|
||||
if (parent.hasActions()) {
|
||||
return false;
|
||||
}
|
||||
// Here goes nothing...
|
||||
return true;
|
||||
}
|
||||
|
||||
private void cancelAnimators(ArrayList<NameValuesHolder> mPendingAnimations) {
|
||||
int size = mPendingAnimations.size();
|
||||
for (int i = 0; i < size; i++) {
|
||||
NameValuesHolder holder = mPendingAnimations.get(i);
|
||||
int property = RenderNodeAnimator.mapViewPropertyToRenderProperty(holder.mNameConstant);
|
||||
if (mAnimators[property] != null) {
|
||||
mAnimators[property].cancel();
|
||||
mAnimators[property] = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -24,10 +24,13 @@ import android.view.Choreographer;
|
||||
* Interpolator that builds a lookup table to use. This is a fallback for
|
||||
* building a native interpolator from a TimeInterpolator that is not marked
|
||||
* with {@link HasNativeInterpolator}
|
||||
*
|
||||
* This implements TimeInterpolator to allow for easier interop with Animators
|
||||
*/
|
||||
@HasNativeInterpolator
|
||||
public class FallbackLUTInterpolator implements NativeInterpolatorFactory {
|
||||
public class FallbackLUTInterpolator implements NativeInterpolatorFactory, TimeInterpolator {
|
||||
|
||||
private TimeInterpolator mSourceInterpolator;
|
||||
private final float mLut[];
|
||||
|
||||
/**
|
||||
@@ -35,6 +38,7 @@ public class FallbackLUTInterpolator implements NativeInterpolatorFactory {
|
||||
* interpolator creation
|
||||
*/
|
||||
public FallbackLUTInterpolator(TimeInterpolator interpolator, long duration) {
|
||||
mSourceInterpolator = interpolator;
|
||||
mLut = createLUT(interpolator, duration);
|
||||
}
|
||||
|
||||
@@ -63,4 +67,9 @@ public class FallbackLUTInterpolator implements NativeInterpolatorFactory {
|
||||
float[] lut = createLUT(interpolator, duration);
|
||||
return NativeInterpolatorFactoryHelper.createLutInterpolator(lut);
|
||||
}
|
||||
|
||||
@Override
|
||||
public float getInterpolation(float input) {
|
||||
return mSourceInterpolator.getInterpolation(input);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
LOCAL_PATH:= $(call my-dir)
|
||||
include $(CLEAR_VARS)
|
||||
|
||||
LOCAL_MODULE_TAGS := optional
|
||||
LOCAL_MODULE_TAGS := tests
|
||||
|
||||
# Only compile source java files in this apk.
|
||||
LOCAL_SRC_FILES := $(call all-java-files-under, src)
|
||||
|
||||
@@ -4,10 +4,6 @@
|
||||
android:versionCode="1"
|
||||
android:versionName="1.0" >
|
||||
|
||||
<uses-sdk
|
||||
android:minSdkVersion="18"
|
||||
android:targetSdkVersion="18" />
|
||||
|
||||
<application
|
||||
android:allowBackup="true"
|
||||
android:icon="@drawable/ic_launcher"
|
||||
|
||||
Reference in New Issue
Block a user