Add AnimatedVectorDrawable
Currently as a hidden class. It can support many the animations now as far as ObjectAnimator and hierarchical group can support. And we don't have path morphing yet. Also support the Animator / Interpolator inflation from Context and Resources. Change-Id: I948bbdf7373ad291171eed0b497959dce8c2edf3
This commit is contained in:
@@ -17,6 +17,7 @@ package android.animation;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.res.Resources;
|
||||
import android.content.res.Resources.Theme;
|
||||
import android.content.res.TypedArray;
|
||||
import android.content.res.XmlResourceParser;
|
||||
import android.content.res.Resources.NotFoundException;
|
||||
@@ -25,6 +26,9 @@ import android.util.StateSet;
|
||||
import android.util.TypedValue;
|
||||
import android.util.Xml;
|
||||
import android.view.animation.AnimationUtils;
|
||||
|
||||
import com.android.internal.R;
|
||||
|
||||
import org.xmlpull.v1.XmlPullParser;
|
||||
import org.xmlpull.v1.XmlPullParserException;
|
||||
|
||||
@@ -66,11 +70,26 @@ public class AnimatorInflater {
|
||||
*/
|
||||
public static Animator loadAnimator(Context context, int id)
|
||||
throws NotFoundException {
|
||||
return loadAnimator(context.getResources(), context.getTheme(), id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads an {@link Animator} object from a resource
|
||||
*
|
||||
* @param resources The resources
|
||||
* @param theme The theme
|
||||
* @param id The resource id of the animation to load
|
||||
* @return The animator object reference by the specified id
|
||||
* @throws android.content.res.Resources.NotFoundException when the animation cannot be loaded
|
||||
* @hide
|
||||
*/
|
||||
public static Animator loadAnimator(Resources resources, Theme theme, int id)
|
||||
throws NotFoundException {
|
||||
|
||||
XmlResourceParser parser = null;
|
||||
try {
|
||||
parser = context.getResources().getAnimation(id);
|
||||
return createAnimatorFromXml(context, parser);
|
||||
parser = resources.getAnimation(id);
|
||||
return createAnimatorFromXml(resources, theme, parser);
|
||||
} catch (XmlPullParserException ex) {
|
||||
Resources.NotFoundException rnf =
|
||||
new Resources.NotFoundException("Can't load animation resource ID #0x" +
|
||||
@@ -150,7 +169,8 @@ public class AnimatorInflater {
|
||||
|
||||
}
|
||||
if (animator == null) {
|
||||
animator = createAnimatorFromXml(context, parser);
|
||||
animator = createAnimatorFromXml(context.getResources(),
|
||||
context.getTheme(), parser);
|
||||
}
|
||||
|
||||
if (animator == null) {
|
||||
@@ -166,103 +186,8 @@ public class AnimatorInflater {
|
||||
}
|
||||
}
|
||||
|
||||
private static Animator createAnimatorFromXml(Context c, XmlPullParser parser)
|
||||
throws XmlPullParserException, IOException {
|
||||
return createAnimatorFromXml(c, parser, Xml.asAttributeSet(parser), null, 0);
|
||||
}
|
||||
|
||||
private static Animator createAnimatorFromXml(Context c, XmlPullParser parser,
|
||||
AttributeSet attrs, AnimatorSet parent, int sequenceOrdering)
|
||||
throws XmlPullParserException, IOException {
|
||||
|
||||
Animator anim = null;
|
||||
ArrayList<Animator> childAnims = null;
|
||||
|
||||
// Make sure we are on a start tag.
|
||||
int type;
|
||||
int depth = parser.getDepth();
|
||||
|
||||
while (((type=parser.next()) != XmlPullParser.END_TAG || parser.getDepth() > depth)
|
||||
&& type != XmlPullParser.END_DOCUMENT) {
|
||||
|
||||
if (type != XmlPullParser.START_TAG) {
|
||||
continue;
|
||||
}
|
||||
|
||||
String name = parser.getName();
|
||||
|
||||
if (name.equals("objectAnimator")) {
|
||||
anim = loadObjectAnimator(c, attrs);
|
||||
} else if (name.equals("animator")) {
|
||||
anim = loadAnimator(c, attrs, null);
|
||||
} else if (name.equals("set")) {
|
||||
anim = new AnimatorSet();
|
||||
TypedArray a = c.obtainStyledAttributes(attrs,
|
||||
com.android.internal.R.styleable.AnimatorSet);
|
||||
int ordering = a.getInt(com.android.internal.R.styleable.AnimatorSet_ordering,
|
||||
TOGETHER);
|
||||
createAnimatorFromXml(c, parser, attrs, (AnimatorSet) anim, ordering);
|
||||
a.recycle();
|
||||
} else {
|
||||
throw new RuntimeException("Unknown animator name: " + parser.getName());
|
||||
}
|
||||
|
||||
if (parent != null) {
|
||||
if (childAnims == null) {
|
||||
childAnims = new ArrayList<Animator>();
|
||||
}
|
||||
childAnims.add(anim);
|
||||
}
|
||||
}
|
||||
if (parent != null && childAnims != null) {
|
||||
Animator[] animsArray = new Animator[childAnims.size()];
|
||||
int index = 0;
|
||||
for (Animator a : childAnims) {
|
||||
animsArray[index++] = a;
|
||||
}
|
||||
if (sequenceOrdering == TOGETHER) {
|
||||
parent.playTogether(animsArray);
|
||||
} else {
|
||||
parent.playSequentially(animsArray);
|
||||
}
|
||||
}
|
||||
|
||||
return anim;
|
||||
|
||||
}
|
||||
|
||||
private static ObjectAnimator loadObjectAnimator(Context context, AttributeSet attrs)
|
||||
throws NotFoundException {
|
||||
|
||||
ObjectAnimator anim = new ObjectAnimator();
|
||||
|
||||
loadAnimator(context, attrs, anim);
|
||||
|
||||
TypedArray a =
|
||||
context.obtainStyledAttributes(attrs, com.android.internal.R.styleable.PropertyAnimator);
|
||||
|
||||
String propertyName = a.getString(com.android.internal.R.styleable.PropertyAnimator_propertyName);
|
||||
|
||||
anim.setPropertyName(propertyName);
|
||||
|
||||
a.recycle();
|
||||
|
||||
return anim;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new animation whose parameters come from the specified context and
|
||||
* attributes set.
|
||||
*
|
||||
* @param context the application environment
|
||||
* @param attrs the set of attributes holding the animation parameters
|
||||
*/
|
||||
private static ValueAnimator loadAnimator(Context context, AttributeSet attrs, ValueAnimator anim)
|
||||
throws NotFoundException {
|
||||
|
||||
TypedArray a =
|
||||
context.obtainStyledAttributes(attrs, com.android.internal.R.styleable.Animator);
|
||||
|
||||
private static void parseAnimatorFromTypeArray(ValueAnimator anim, TypedArray a) {
|
||||
long duration = a.getInt(com.android.internal.R.styleable.Animator_duration, 300);
|
||||
|
||||
long startDelay = a.getInt(com.android.internal.R.styleable.Animator_startOffset, 0);
|
||||
@@ -378,11 +303,123 @@ public class AnimatorInflater {
|
||||
if (evaluator != null) {
|
||||
anim.setEvaluator(evaluator);
|
||||
}
|
||||
}
|
||||
|
||||
private static Animator createAnimatorFromXml(Resources res, Theme theme, XmlPullParser parser)
|
||||
throws XmlPullParserException, IOException {
|
||||
return createAnimatorFromXml(res, theme, parser, Xml.asAttributeSet(parser), null, 0);
|
||||
}
|
||||
|
||||
private static Animator createAnimatorFromXml(Resources res, Theme theme, XmlPullParser parser,
|
||||
AttributeSet attrs, AnimatorSet parent, int sequenceOrdering)
|
||||
throws XmlPullParserException, IOException {
|
||||
|
||||
Animator anim = null;
|
||||
ArrayList<Animator> childAnims = null;
|
||||
|
||||
// Make sure we are on a start tag.
|
||||
int type;
|
||||
int depth = parser.getDepth();
|
||||
|
||||
while (((type = parser.next()) != XmlPullParser.END_TAG || parser.getDepth() > depth)
|
||||
&& type != XmlPullParser.END_DOCUMENT) {
|
||||
|
||||
if (type != XmlPullParser.START_TAG) {
|
||||
continue;
|
||||
}
|
||||
|
||||
String name = parser.getName();
|
||||
|
||||
if (name.equals("objectAnimator")) {
|
||||
anim = loadObjectAnimator(res, theme, attrs);
|
||||
} else if (name.equals("animator")) {
|
||||
anim = loadAnimator(res, theme, attrs, null);
|
||||
} else if (name.equals("set")) {
|
||||
anim = new AnimatorSet();
|
||||
TypedArray a;
|
||||
if (theme != null) {
|
||||
a = theme.obtainStyledAttributes(attrs, com.android.internal.R.styleable.AnimatorSet, 0, 0);
|
||||
} else {
|
||||
a = res.obtainAttributes(attrs, com.android.internal.R.styleable.AnimatorSet);
|
||||
}
|
||||
int ordering = a.getInt(com.android.internal.R.styleable.AnimatorSet_ordering,
|
||||
TOGETHER);
|
||||
createAnimatorFromXml(res, theme, parser, attrs, (AnimatorSet) anim, ordering);
|
||||
a.recycle();
|
||||
} else {
|
||||
throw new RuntimeException("Unknown animator name: " + parser.getName());
|
||||
}
|
||||
|
||||
if (parent != null) {
|
||||
if (childAnims == null) {
|
||||
childAnims = new ArrayList<Animator>();
|
||||
}
|
||||
childAnims.add(anim);
|
||||
}
|
||||
}
|
||||
if (parent != null && childAnims != null) {
|
||||
Animator[] animsArray = new Animator[childAnims.size()];
|
||||
int index = 0;
|
||||
for (Animator a : childAnims) {
|
||||
animsArray[index++] = a;
|
||||
}
|
||||
if (sequenceOrdering == TOGETHER) {
|
||||
parent.playTogether(animsArray);
|
||||
} else {
|
||||
parent.playSequentially(animsArray);
|
||||
}
|
||||
}
|
||||
|
||||
return anim;
|
||||
|
||||
}
|
||||
|
||||
private static ObjectAnimator loadObjectAnimator(Resources res, Theme theme, AttributeSet attrs)
|
||||
throws NotFoundException {
|
||||
ObjectAnimator anim = new ObjectAnimator();
|
||||
|
||||
loadAnimator(res, theme, attrs, anim);
|
||||
|
||||
TypedArray a;
|
||||
if (theme != null) {
|
||||
a = theme.obtainStyledAttributes(attrs, R.styleable.PropertyAnimator, 0, 0);
|
||||
} else {
|
||||
a = res.obtainAttributes(attrs, R.styleable.PropertyAnimator);
|
||||
}
|
||||
|
||||
String propertyName = a.getString(R.styleable.PropertyAnimator_propertyName);
|
||||
|
||||
anim.setPropertyName(propertyName);
|
||||
|
||||
a.recycle();
|
||||
|
||||
return anim;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new animation whose parameters come from the specified context
|
||||
* and attributes set.
|
||||
*
|
||||
* @param res The resources
|
||||
* @param attrs The set of attributes holding the animation parameters
|
||||
*/
|
||||
private static ValueAnimator loadAnimator(Resources res, Theme theme,
|
||||
AttributeSet attrs, ValueAnimator anim)
|
||||
throws NotFoundException {
|
||||
|
||||
TypedArray a;
|
||||
if (theme != null) {
|
||||
a = theme.obtainStyledAttributes(attrs, R.styleable.Animator, 0, 0);
|
||||
} else {
|
||||
a = res.obtainAttributes(attrs, R.styleable.Animator);
|
||||
}
|
||||
|
||||
parseAnimatorFromTypeArray(anim, a);
|
||||
|
||||
final int resID =
|
||||
a.getResourceId(com.android.internal.R.styleable.Animator_interpolator, 0);
|
||||
if (resID > 0) {
|
||||
anim.setInterpolator(AnimationUtils.loadInterpolator(context, resID));
|
||||
anim.setInterpolator(AnimationUtils.loadInterpolator(res, theme, resID));
|
||||
}
|
||||
a.recycle();
|
||||
|
||||
|
||||
@@ -17,15 +17,18 @@
|
||||
package android.view.animation;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.res.Resources;
|
||||
import android.content.res.Resources.Theme;
|
||||
import android.content.res.TypedArray;
|
||||
import android.util.AttributeSet;
|
||||
|
||||
import com.android.internal.R;
|
||||
import com.android.internal.view.animation.HasNativeInterpolator;
|
||||
import com.android.internal.view.animation.NativeInterpolatorFactory;
|
||||
import com.android.internal.view.animation.NativeInterpolatorFactoryHelper;
|
||||
|
||||
/**
|
||||
* An interpolator where the rate of change starts out slowly and
|
||||
* An interpolator where the rate of change starts out slowly and
|
||||
* and then accelerates.
|
||||
*
|
||||
*/
|
||||
@@ -38,10 +41,10 @@ public class AccelerateInterpolator implements Interpolator, NativeInterpolatorF
|
||||
mFactor = 1.0f;
|
||||
mDoubleFactor = 2.0;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
*
|
||||
* @param factor Degree to which the animation should be eased. Seting
|
||||
* factor to 1.0f produces a y=x^2 parabola. Increasing factor above
|
||||
* 1.0f exaggerates the ease-in effect (i.e., it starts even
|
||||
@@ -51,17 +54,26 @@ public class AccelerateInterpolator implements Interpolator, NativeInterpolatorF
|
||||
mFactor = factor;
|
||||
mDoubleFactor = 2 * mFactor;
|
||||
}
|
||||
|
||||
|
||||
public AccelerateInterpolator(Context context, AttributeSet attrs) {
|
||||
TypedArray a =
|
||||
context.obtainStyledAttributes(attrs, com.android.internal.R.styleable.AccelerateInterpolator);
|
||||
|
||||
mFactor = a.getFloat(com.android.internal.R.styleable.AccelerateInterpolator_factor, 1.0f);
|
||||
this(context.getResources(), context.getTheme(), attrs);
|
||||
}
|
||||
|
||||
/** @hide */
|
||||
public AccelerateInterpolator(Resources res, Theme theme, AttributeSet attrs) {
|
||||
TypedArray a;
|
||||
if (theme != null) {
|
||||
a = theme.obtainStyledAttributes(attrs, R.styleable.AccelerateInterpolator, 0, 0);
|
||||
} else {
|
||||
a = res.obtainAttributes(attrs, R.styleable.AccelerateInterpolator);
|
||||
}
|
||||
|
||||
mFactor = a.getFloat(R.styleable.AccelerateInterpolator_factor, 1.0f);
|
||||
mDoubleFactor = 2 * mFactor;
|
||||
|
||||
a.recycle();
|
||||
}
|
||||
|
||||
|
||||
public float getInterpolation(float input) {
|
||||
if (mFactor == 1.0f) {
|
||||
return input * input;
|
||||
|
||||
@@ -20,6 +20,8 @@ import org.xmlpull.v1.XmlPullParser;
|
||||
import org.xmlpull.v1.XmlPullParserException;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.res.Resources;
|
||||
import android.content.res.Resources.Theme;
|
||||
import android.content.res.XmlResourceParser;
|
||||
import android.content.res.Resources.NotFoundException;
|
||||
import android.util.AttributeSet;
|
||||
@@ -143,7 +145,7 @@ public class AnimationUtils {
|
||||
*/
|
||||
public static LayoutAnimationController loadLayoutAnimation(Context context, int id)
|
||||
throws NotFoundException {
|
||||
|
||||
|
||||
XmlResourceParser parser = null;
|
||||
try {
|
||||
parser = context.getResources().getAnimation(id);
|
||||
@@ -201,7 +203,7 @@ public class AnimationUtils {
|
||||
/**
|
||||
* Make an animation for objects becoming visible. Uses a slide and fade
|
||||
* effect.
|
||||
*
|
||||
*
|
||||
* @param c Context for loading resources
|
||||
* @param fromLeft is the object to be animated coming from the left
|
||||
* @return The new animation
|
||||
@@ -218,11 +220,11 @@ public class AnimationUtils {
|
||||
a.setStartTime(currentAnimationTimeMillis());
|
||||
return a;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Make an animation for objects becoming invisible. Uses a slide and fade
|
||||
* effect.
|
||||
*
|
||||
*
|
||||
* @param c Context for loading resources
|
||||
* @param toRight is the object to be animated exiting to the right
|
||||
* @return The new animation
|
||||
@@ -234,17 +236,17 @@ public class AnimationUtils {
|
||||
} else {
|
||||
a = AnimationUtils.loadAnimation(c, com.android.internal.R.anim.slide_out_left);
|
||||
}
|
||||
|
||||
|
||||
a.setInterpolator(new AccelerateInterpolator());
|
||||
a.setStartTime(currentAnimationTimeMillis());
|
||||
return a;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Make an animation for objects becoming visible. Uses a slide up and fade
|
||||
* effect.
|
||||
*
|
||||
*
|
||||
* @param c Context for loading resources
|
||||
* @return The new animation
|
||||
*/
|
||||
@@ -255,10 +257,10 @@ public class AnimationUtils {
|
||||
a.setStartTime(currentAnimationTimeMillis());
|
||||
return a;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Loads an {@link Interpolator} object from a resource
|
||||
*
|
||||
*
|
||||
* @param context Application context used to access resources
|
||||
* @param id The resource id of the animation to load
|
||||
* @return The animation object reference by the specified id
|
||||
@@ -268,7 +270,7 @@ public class AnimationUtils {
|
||||
XmlResourceParser parser = null;
|
||||
try {
|
||||
parser = context.getResources().getAnimation(id);
|
||||
return createInterpolatorFromXml(context, parser);
|
||||
return createInterpolatorFromXml(context.getResources(), context.getTheme(), parser);
|
||||
} catch (XmlPullParserException ex) {
|
||||
NotFoundException rnf = new NotFoundException("Can't load animation resource ID #0x" +
|
||||
Integer.toHexString(id));
|
||||
@@ -284,54 +286,84 @@ public class AnimationUtils {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static Interpolator createInterpolatorFromXml(Context c, XmlPullParser parser)
|
||||
|
||||
/**
|
||||
* Loads an {@link Interpolator} object from a resource
|
||||
*
|
||||
* @param res The resources
|
||||
* @param id The resource id of the animation to load
|
||||
* @return The interpolator object reference by the specified id
|
||||
* @throws NotFoundException
|
||||
* @hide
|
||||
*/
|
||||
public static Interpolator loadInterpolator(Resources res, Theme theme, int id) throws NotFoundException {
|
||||
XmlResourceParser parser = null;
|
||||
try {
|
||||
parser = res.getAnimation(id);
|
||||
return createInterpolatorFromXml(res, theme, parser);
|
||||
} catch (XmlPullParserException ex) {
|
||||
NotFoundException rnf = new NotFoundException("Can't load animation resource ID #0x" +
|
||||
Integer.toHexString(id));
|
||||
rnf.initCause(ex);
|
||||
throw rnf;
|
||||
} catch (IOException ex) {
|
||||
NotFoundException rnf = new NotFoundException("Can't load animation resource ID #0x" +
|
||||
Integer.toHexString(id));
|
||||
rnf.initCause(ex);
|
||||
throw rnf;
|
||||
} finally {
|
||||
if (parser != null)
|
||||
parser.close();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static Interpolator createInterpolatorFromXml(Resources res, Theme theme, XmlPullParser parser)
|
||||
throws XmlPullParserException, IOException {
|
||||
|
||||
|
||||
Interpolator interpolator = null;
|
||||
|
||||
|
||||
// Make sure we are on a start tag.
|
||||
int type;
|
||||
int depth = parser.getDepth();
|
||||
|
||||
while (((type=parser.next()) != XmlPullParser.END_TAG || parser.getDepth() > depth)
|
||||
&& type != XmlPullParser.END_DOCUMENT) {
|
||||
while (((type = parser.next()) != XmlPullParser.END_TAG || parser.getDepth() > depth)
|
||||
&& type != XmlPullParser.END_DOCUMENT) {
|
||||
|
||||
if (type != XmlPullParser.START_TAG) {
|
||||
continue;
|
||||
}
|
||||
|
||||
AttributeSet attrs = Xml.asAttributeSet(parser);
|
||||
|
||||
String name = parser.getName();
|
||||
|
||||
|
||||
|
||||
String name = parser.getName();
|
||||
|
||||
if (name.equals("linearInterpolator")) {
|
||||
interpolator = new LinearInterpolator(c, attrs);
|
||||
interpolator = new LinearInterpolator();
|
||||
} else if (name.equals("accelerateInterpolator")) {
|
||||
interpolator = new AccelerateInterpolator(c, attrs);
|
||||
interpolator = new AccelerateInterpolator(res, theme, attrs);
|
||||
} else if (name.equals("decelerateInterpolator")) {
|
||||
interpolator = new DecelerateInterpolator(c, attrs);
|
||||
} else if (name.equals("accelerateDecelerateInterpolator")) {
|
||||
interpolator = new AccelerateDecelerateInterpolator(c, attrs);
|
||||
} else if (name.equals("cycleInterpolator")) {
|
||||
interpolator = new CycleInterpolator(c, attrs);
|
||||
interpolator = new DecelerateInterpolator(res, theme, attrs);
|
||||
} else if (name.equals("accelerateDecelerateInterpolator")) {
|
||||
interpolator = new AccelerateDecelerateInterpolator();
|
||||
} else if (name.equals("cycleInterpolator")) {
|
||||
interpolator = new CycleInterpolator(res, theme, attrs);
|
||||
} else if (name.equals("anticipateInterpolator")) {
|
||||
interpolator = new AnticipateInterpolator(c, attrs);
|
||||
interpolator = new AnticipateInterpolator(res, theme, attrs);
|
||||
} else if (name.equals("overshootInterpolator")) {
|
||||
interpolator = new OvershootInterpolator(c, attrs);
|
||||
interpolator = new OvershootInterpolator(res, theme, attrs);
|
||||
} else if (name.equals("anticipateOvershootInterpolator")) {
|
||||
interpolator = new AnticipateOvershootInterpolator(c, attrs);
|
||||
interpolator = new AnticipateOvershootInterpolator(res, theme, attrs);
|
||||
} else if (name.equals("bounceInterpolator")) {
|
||||
interpolator = new BounceInterpolator(c, attrs);
|
||||
interpolator = new BounceInterpolator();
|
||||
} else if (name.equals("pathInterpolator")) {
|
||||
interpolator = new PathInterpolator(c, attrs);
|
||||
interpolator = new PathInterpolator(res, theme, attrs);
|
||||
} else {
|
||||
throw new RuntimeException("Unknown interpolator name: " + parser.getName());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
return interpolator;
|
||||
|
||||
}
|
||||
|
||||
@@ -17,9 +17,12 @@
|
||||
package android.view.animation;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.res.Resources;
|
||||
import android.content.res.TypedArray;
|
||||
import android.content.res.Resources.Theme;
|
||||
import android.util.AttributeSet;
|
||||
|
||||
import com.android.internal.R;
|
||||
import com.android.internal.view.animation.HasNativeInterpolator;
|
||||
import com.android.internal.view.animation.NativeInterpolatorFactory;
|
||||
import com.android.internal.view.animation.NativeInterpolatorFactoryHelper;
|
||||
@@ -45,11 +48,20 @@ public class AnticipateInterpolator implements Interpolator, NativeInterpolatorF
|
||||
}
|
||||
|
||||
public AnticipateInterpolator(Context context, AttributeSet attrs) {
|
||||
TypedArray a = context.obtainStyledAttributes(attrs,
|
||||
com.android.internal.R.styleable.AnticipateInterpolator);
|
||||
this(context.getResources(), context.getTheme(), attrs);
|
||||
}
|
||||
|
||||
/** @hide */
|
||||
public AnticipateInterpolator(Resources res, Theme theme, AttributeSet attrs) {
|
||||
TypedArray a;
|
||||
if (theme != null) {
|
||||
a = theme.obtainStyledAttributes(attrs, R.styleable.AnticipateInterpolator, 0, 0);
|
||||
} else {
|
||||
a = res.obtainAttributes(attrs, R.styleable.AnticipateInterpolator);
|
||||
}
|
||||
|
||||
mTension =
|
||||
a.getFloat(com.android.internal.R.styleable.AnticipateInterpolator_tension, 2.0f);
|
||||
a.getFloat(R.styleable.AnticipateInterpolator_tension, 2.0f);
|
||||
|
||||
a.recycle();
|
||||
}
|
||||
|
||||
@@ -17,6 +17,8 @@
|
||||
package android.view.animation;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.res.Resources;
|
||||
import android.content.res.Resources.Theme;
|
||||
import android.content.res.TypedArray;
|
||||
import android.util.AttributeSet;
|
||||
|
||||
@@ -62,7 +64,17 @@ public class AnticipateOvershootInterpolator implements Interpolator, NativeInte
|
||||
}
|
||||
|
||||
public AnticipateOvershootInterpolator(Context context, AttributeSet attrs) {
|
||||
TypedArray a = context.obtainStyledAttributes(attrs, AnticipateOvershootInterpolator);
|
||||
this(context.getResources(), context.getTheme(), attrs);
|
||||
}
|
||||
|
||||
/** @hide */
|
||||
public AnticipateOvershootInterpolator(Resources res, Theme theme, AttributeSet attrs) {
|
||||
TypedArray a;
|
||||
if (theme != null) {
|
||||
a = theme.obtainStyledAttributes(attrs, AnticipateOvershootInterpolator, 0, 0);
|
||||
} else {
|
||||
a = res.obtainAttributes(attrs, AnticipateOvershootInterpolator);
|
||||
}
|
||||
|
||||
mTension = a.getFloat(AnticipateOvershootInterpolator_tension, 2.0f) *
|
||||
a.getFloat(AnticipateOvershootInterpolator_extraTension, 1.5f);
|
||||
|
||||
@@ -17,9 +17,12 @@
|
||||
package android.view.animation;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.res.Resources;
|
||||
import android.content.res.TypedArray;
|
||||
import android.content.res.Resources.Theme;
|
||||
import android.util.AttributeSet;
|
||||
|
||||
import com.android.internal.R;
|
||||
import com.android.internal.view.animation.HasNativeInterpolator;
|
||||
import com.android.internal.view.animation.NativeInterpolatorFactory;
|
||||
import com.android.internal.view.animation.NativeInterpolatorFactoryHelper;
|
||||
@@ -34,20 +37,29 @@ public class CycleInterpolator implements Interpolator, NativeInterpolatorFactor
|
||||
public CycleInterpolator(float cycles) {
|
||||
mCycles = cycles;
|
||||
}
|
||||
|
||||
|
||||
public CycleInterpolator(Context context, AttributeSet attrs) {
|
||||
TypedArray a =
|
||||
context.obtainStyledAttributes(attrs, com.android.internal.R.styleable.CycleInterpolator);
|
||||
|
||||
mCycles = a.getFloat(com.android.internal.R.styleable.CycleInterpolator_cycles, 1.0f);
|
||||
|
||||
this(context.getResources(), context.getTheme(), attrs);
|
||||
}
|
||||
|
||||
/** @hide */
|
||||
public CycleInterpolator(Resources resources, Theme theme, AttributeSet attrs) {
|
||||
TypedArray a;
|
||||
if (theme != null) {
|
||||
a = theme.obtainStyledAttributes(attrs, R.styleable.CycleInterpolator, 0, 0);
|
||||
} else {
|
||||
a = resources.obtainAttributes(attrs, R.styleable.CycleInterpolator);
|
||||
}
|
||||
|
||||
mCycles = a.getFloat(R.styleable.CycleInterpolator_cycles, 1.0f);
|
||||
|
||||
a.recycle();
|
||||
}
|
||||
|
||||
|
||||
public float getInterpolation(float input) {
|
||||
return (float)(Math.sin(2 * mCycles * Math.PI * input));
|
||||
}
|
||||
|
||||
|
||||
private float mCycles;
|
||||
|
||||
/** @hide */
|
||||
|
||||
@@ -17,15 +17,18 @@
|
||||
package android.view.animation;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.res.Resources;
|
||||
import android.content.res.TypedArray;
|
||||
import android.content.res.Resources.Theme;
|
||||
import android.util.AttributeSet;
|
||||
|
||||
import com.android.internal.R;
|
||||
import com.android.internal.view.animation.HasNativeInterpolator;
|
||||
import com.android.internal.view.animation.NativeInterpolatorFactory;
|
||||
import com.android.internal.view.animation.NativeInterpolatorFactoryHelper;
|
||||
|
||||
/**
|
||||
* An interpolator where the rate of change starts out quickly and
|
||||
* An interpolator where the rate of change starts out quickly and
|
||||
* and then decelerates.
|
||||
*
|
||||
*/
|
||||
@@ -36,7 +39,7 @@ public class DecelerateInterpolator implements Interpolator, NativeInterpolatorF
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
*
|
||||
* @param factor Degree to which the animation should be eased. Setting factor to 1.0f produces
|
||||
* an upside-down y=x^2 parabola. Increasing factor above 1.0f makes exaggerates the
|
||||
* ease-out effect (i.e., it starts even faster and ends evens slower)
|
||||
@@ -44,16 +47,25 @@ public class DecelerateInterpolator implements Interpolator, NativeInterpolatorF
|
||||
public DecelerateInterpolator(float factor) {
|
||||
mFactor = factor;
|
||||
}
|
||||
|
||||
|
||||
public DecelerateInterpolator(Context context, AttributeSet attrs) {
|
||||
TypedArray a =
|
||||
context.obtainStyledAttributes(attrs, com.android.internal.R.styleable.DecelerateInterpolator);
|
||||
|
||||
mFactor = a.getFloat(com.android.internal.R.styleable.DecelerateInterpolator_factor, 1.0f);
|
||||
|
||||
this(context.getResources(), context.getTheme(), attrs);
|
||||
}
|
||||
|
||||
/** @hide */
|
||||
public DecelerateInterpolator(Resources res, Theme theme, AttributeSet attrs) {
|
||||
TypedArray a;
|
||||
if (theme != null) {
|
||||
a = theme.obtainStyledAttributes(attrs, R.styleable.DecelerateInterpolator, 0, 0);
|
||||
} else {
|
||||
a = res.obtainAttributes(attrs, R.styleable.DecelerateInterpolator);
|
||||
}
|
||||
|
||||
mFactor = a.getFloat(R.styleable.DecelerateInterpolator_factor, 1.0f);
|
||||
|
||||
a.recycle();
|
||||
}
|
||||
|
||||
|
||||
public float getInterpolation(float input) {
|
||||
float result;
|
||||
if (mFactor == 1.0f) {
|
||||
@@ -63,7 +75,7 @@ public class DecelerateInterpolator implements Interpolator, NativeInterpolatorF
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
private float mFactor = 1.0f;
|
||||
|
||||
/** @hide */
|
||||
|
||||
@@ -17,9 +17,12 @@
|
||||
package android.view.animation;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.res.Resources;
|
||||
import android.content.res.Resources.Theme;
|
||||
import android.content.res.TypedArray;
|
||||
import android.util.AttributeSet;
|
||||
|
||||
import com.android.internal.R;
|
||||
import com.android.internal.view.animation.HasNativeInterpolator;
|
||||
import com.android.internal.view.animation.NativeInterpolatorFactory;
|
||||
import com.android.internal.view.animation.NativeInterpolatorFactoryHelper;
|
||||
@@ -46,11 +49,20 @@ public class OvershootInterpolator implements Interpolator, NativeInterpolatorFa
|
||||
}
|
||||
|
||||
public OvershootInterpolator(Context context, AttributeSet attrs) {
|
||||
TypedArray a = context.obtainStyledAttributes(attrs,
|
||||
com.android.internal.R.styleable.OvershootInterpolator);
|
||||
this(context.getResources(), context.getTheme(), attrs);
|
||||
}
|
||||
|
||||
/** @hide */
|
||||
public OvershootInterpolator(Resources res, Theme theme, AttributeSet attrs) {
|
||||
TypedArray a;
|
||||
if (theme != null) {
|
||||
a = theme.obtainStyledAttributes(attrs, R.styleable.OvershootInterpolator, 0, 0);
|
||||
} else {
|
||||
a = res.obtainAttributes(attrs, R.styleable.OvershootInterpolator);
|
||||
}
|
||||
|
||||
mTension =
|
||||
a.getFloat(com.android.internal.R.styleable.OvershootInterpolator_tension, 2.0f);
|
||||
a.getFloat(R.styleable.OvershootInterpolator_tension, 2.0f);
|
||||
|
||||
a.recycle();
|
||||
}
|
||||
|
||||
@@ -16,11 +16,15 @@
|
||||
package android.view.animation;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.res.Resources;
|
||||
import android.content.res.Resources.Theme;
|
||||
import android.content.res.TypedArray;
|
||||
import android.graphics.Path;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.InflateException;
|
||||
|
||||
import com.android.internal.R;
|
||||
|
||||
/**
|
||||
* An interpolator that can traverse a Path that extends from <code>Point</code>
|
||||
* <code>(0, 0)</code> to <code>(1, 1)</code>. The x coordinate along the <code>Path</code>
|
||||
@@ -81,18 +85,33 @@ public class PathInterpolator implements Interpolator {
|
||||
}
|
||||
|
||||
public PathInterpolator(Context context, AttributeSet attrs) {
|
||||
TypedArray a = context.obtainStyledAttributes(attrs,
|
||||
com.android.internal.R.styleable.PathInterpolator);
|
||||
if (!a.hasValue(com.android.internal.R.styleable.PathInterpolator_controlX1)) {
|
||||
this(context.getResources(), context.getTheme(), attrs);
|
||||
}
|
||||
|
||||
/** @hide */
|
||||
public PathInterpolator(Resources res, Theme theme, AttributeSet attrs) {
|
||||
TypedArray a;
|
||||
if (theme != null) {
|
||||
a = theme.obtainStyledAttributes(attrs, R.styleable.PathInterpolator, 0, 0);
|
||||
} else {
|
||||
a = res.obtainAttributes(attrs, R.styleable.PathInterpolator);
|
||||
}
|
||||
parseInterpolatorFromTypeArray(a);
|
||||
|
||||
a.recycle();
|
||||
}
|
||||
|
||||
private void parseInterpolatorFromTypeArray(TypedArray a) {
|
||||
if (!a.hasValue(R.styleable.PathInterpolator_controlX1)) {
|
||||
throw new InflateException("pathInterpolator requires the controlX1 attribute");
|
||||
} else if (!a.hasValue(com.android.internal.R.styleable.PathInterpolator_controlY1)) {
|
||||
} else if (!a.hasValue(R.styleable.PathInterpolator_controlY1)) {
|
||||
throw new InflateException("pathInterpolator requires the controlY1 attribute");
|
||||
}
|
||||
float x1 = a.getFloat(com.android.internal.R.styleable.PathInterpolator_controlX1, 0);
|
||||
float y1 = a.getFloat(com.android.internal.R.styleable.PathInterpolator_controlY1, 0);
|
||||
float x1 = a.getFloat(R.styleable.PathInterpolator_controlX1, 0);
|
||||
float y1 = a.getFloat(R.styleable.PathInterpolator_controlY1, 0);
|
||||
|
||||
boolean hasX2 = a.hasValue(com.android.internal.R.styleable.PathInterpolator_controlX2);
|
||||
boolean hasY2 = a.hasValue(com.android.internal.R.styleable.PathInterpolator_controlY2);
|
||||
boolean hasX2 = a.hasValue(R.styleable.PathInterpolator_controlX2);
|
||||
boolean hasY2 = a.hasValue(R.styleable.PathInterpolator_controlY2);
|
||||
|
||||
if (hasX2 != hasY2) {
|
||||
throw new InflateException(
|
||||
@@ -102,12 +121,10 @@ public class PathInterpolator implements Interpolator {
|
||||
if (!hasX2) {
|
||||
initQuad(x1, y1);
|
||||
} else {
|
||||
float x2 = a.getFloat(com.android.internal.R.styleable.PathInterpolator_controlX2, 0);
|
||||
float y2 = a.getFloat(com.android.internal.R.styleable.PathInterpolator_controlY2, 0);
|
||||
float x2 = a.getFloat(R.styleable.PathInterpolator_controlX2, 0);
|
||||
float y2 = a.getFloat(R.styleable.PathInterpolator_controlY2, 0);
|
||||
initCubic(x1, y1, x2, y2);
|
||||
}
|
||||
|
||||
a.recycle();
|
||||
}
|
||||
|
||||
private void initQuad(float controlX, float controlY) {
|
||||
|
||||
@@ -4772,7 +4772,7 @@
|
||||
</declare-styleable>
|
||||
|
||||
<!-- ========================== -->
|
||||
<!-- Vector drawable class -->
|
||||
<!-- VectorDrawable class -->
|
||||
<!-- ========================== -->
|
||||
<eat-comment />
|
||||
|
||||
@@ -4792,7 +4792,7 @@
|
||||
<attr name="height" />
|
||||
</declare-styleable>
|
||||
|
||||
<!-- Defines the group used in Vector Drawables. -->
|
||||
<!-- Defines the group used in VectorDrawables. -->
|
||||
<declare-styleable name="VectorDrawableGroup">
|
||||
<!-- The Name of this group -->
|
||||
<attr name="name" />
|
||||
@@ -4814,7 +4814,7 @@
|
||||
<attr name="alpha" />
|
||||
</declare-styleable>
|
||||
|
||||
<!-- Defines the path used in Vector Drawables. -->
|
||||
<!-- Defines the path used in VectorDrawables. -->
|
||||
<declare-styleable name="VectorDrawablePath">
|
||||
<!-- The Name of this path -->
|
||||
<attr name="name" />
|
||||
@@ -4854,6 +4854,25 @@
|
||||
<attr name="strokeMiterLimit" format="float"/>
|
||||
</declare-styleable>
|
||||
|
||||
<!-- ========================== -->
|
||||
<!-- AnimatedVectorDrawable class -->
|
||||
<!-- ========================== -->
|
||||
<eat-comment />
|
||||
|
||||
<!-- Define the AnimatedVectorDrawable. -->
|
||||
<declare-styleable name="AnimatedVectorDrawable">
|
||||
<!-- The static vector drawable. -->
|
||||
<attr name="drawable" />
|
||||
</declare-styleable>
|
||||
|
||||
<!-- Defines the target path or group used in the AnimatedVectorDrawable. -->
|
||||
<declare-styleable name="AnimatedVectorDrawableTarget">
|
||||
<!-- The name of this target path or group -->
|
||||
<attr name="name" />
|
||||
<!-- The animation for this target path or group -->
|
||||
<attr name="animation" />
|
||||
</declare-styleable>
|
||||
|
||||
<!-- ========================== -->
|
||||
<!-- Animation class attributes -->
|
||||
<!-- ========================== -->
|
||||
|
||||
@@ -0,0 +1,250 @@
|
||||
/*
|
||||
* 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.graphics.drawable;
|
||||
|
||||
import android.animation.Animator;
|
||||
import android.animation.AnimatorInflater;
|
||||
import android.content.res.Resources;
|
||||
import android.content.res.Resources.Theme;
|
||||
import android.content.res.TypedArray;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.ColorFilter;
|
||||
import android.graphics.Rect;
|
||||
import android.util.AttributeSet;
|
||||
import android.util.Log;
|
||||
|
||||
import com.android.internal.R;
|
||||
|
||||
import org.xmlpull.v1.XmlPullParser;
|
||||
import org.xmlpull.v1.XmlPullParserException;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
|
||||
/**
|
||||
* AnimatedVectorDrawable can use ObjectAnimator and AnimatorSet to animate
|
||||
* the property of the VectorDrawable.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
public class AnimatedVectorDrawable extends Drawable implements Animatable {
|
||||
private static final String LOGTAG = AnimatedVectorDrawable.class.getSimpleName();
|
||||
|
||||
private static final String ANIMATED_VECTOR = "animated-vector";
|
||||
private static final String TARGET = "target";
|
||||
|
||||
private static final boolean DBG_ANIMATION_VECTOR_DRAWABLE = false;
|
||||
|
||||
private final AnimatedVectorDrawableState mAnimatedVectorState;
|
||||
|
||||
|
||||
public AnimatedVectorDrawable() {
|
||||
mAnimatedVectorState = new AnimatedVectorDrawableState(
|
||||
new AnimatedVectorDrawableState(null));
|
||||
}
|
||||
|
||||
private AnimatedVectorDrawable(AnimatedVectorDrawableState state, Resources res,
|
||||
Theme theme) {
|
||||
// TODO: Correctly handle the constant state for AVD.
|
||||
mAnimatedVectorState = new AnimatedVectorDrawableState(state);
|
||||
if (theme != null && canApplyTheme()) {
|
||||
applyTheme(theme);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public ConstantState getConstantState() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void draw(Canvas canvas) {
|
||||
mAnimatedVectorState.mVectorDrawable.draw(canvas);
|
||||
if (isRunning()) {
|
||||
invalidateSelf();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onBoundsChange(Rect bounds) {
|
||||
mAnimatedVectorState.mVectorDrawable.setBounds(bounds);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getAlpha() {
|
||||
return mAnimatedVectorState.mVectorDrawable.getAlpha();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setAlpha(int alpha) {
|
||||
mAnimatedVectorState.mVectorDrawable.setAlpha(alpha);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setColorFilter(ColorFilter colorFilter) {
|
||||
mAnimatedVectorState.mVectorDrawable.setColorFilter(colorFilter);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getOpacity() {
|
||||
return mAnimatedVectorState.mVectorDrawable.getOpacity();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getIntrinsicWidth() {
|
||||
return mAnimatedVectorState.mVectorDrawable.getIntrinsicWidth();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getIntrinsicHeight() {
|
||||
return mAnimatedVectorState.mVectorDrawable.getIntrinsicHeight();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void inflate(Resources res, XmlPullParser parser, AttributeSet attrs, Theme theme)
|
||||
throws XmlPullParserException, IOException {
|
||||
|
||||
int eventType = parser.getEventType();
|
||||
while (eventType != XmlPullParser.END_DOCUMENT) {
|
||||
if (eventType == XmlPullParser.START_TAG) {
|
||||
final String tagName = parser.getName();
|
||||
if (ANIMATED_VECTOR.equals(tagName)) {
|
||||
final TypedArray a = obtainAttributes(res, theme, attrs,
|
||||
R.styleable.AnimatedVectorDrawable);
|
||||
int drawableRes = a.getResourceId(
|
||||
R.styleable.AnimatedVectorDrawable_drawable, 0);
|
||||
if (drawableRes != 0) {
|
||||
mAnimatedVectorState.mVectorDrawable = (VectorDrawable) res.getDrawable(
|
||||
drawableRes);
|
||||
}
|
||||
a.recycle();
|
||||
} else if (TARGET.equals(tagName)) {
|
||||
final TypedArray a = obtainAttributes(res, theme, attrs,
|
||||
R.styleable.AnimatedVectorDrawableTarget);
|
||||
final String target = a.getString(
|
||||
R.styleable.AnimatedVectorDrawableTarget_name);
|
||||
|
||||
int id = a.getResourceId(
|
||||
R.styleable.AnimatedVectorDrawableTarget_animation, 0);
|
||||
if (id != 0) {
|
||||
Animator objectAnimator = AnimatorInflater.loadAnimator(res, theme, id);
|
||||
setupAnimatorsForTarget(target, objectAnimator);
|
||||
}
|
||||
a.recycle();
|
||||
}
|
||||
}
|
||||
|
||||
eventType = parser.next();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canApplyTheme() {
|
||||
return super.canApplyTheme() || mAnimatedVectorState != null
|
||||
&& mAnimatedVectorState.canApplyTheme();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void applyTheme(Theme t) {
|
||||
super.applyTheme(t);
|
||||
|
||||
final VectorDrawable vectorDrawable = mAnimatedVectorState.mVectorDrawable;
|
||||
if (vectorDrawable != null && vectorDrawable.canApplyTheme()) {
|
||||
vectorDrawable.applyTheme(t);
|
||||
}
|
||||
}
|
||||
|
||||
private static class AnimatedVectorDrawableState extends ConstantState {
|
||||
int mChangingConfigurations;
|
||||
VectorDrawable mVectorDrawable;
|
||||
ArrayList<Animator> mAnimators;
|
||||
|
||||
public AnimatedVectorDrawableState(AnimatedVectorDrawableState copy) {
|
||||
if (copy != null) {
|
||||
mChangingConfigurations = copy.mChangingConfigurations;
|
||||
// TODO: Make sure the constant state are handled correctly.
|
||||
mVectorDrawable = new VectorDrawable();
|
||||
mAnimators = new ArrayList<Animator>();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Drawable newDrawable() {
|
||||
return new AnimatedVectorDrawable(this, null, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Drawable newDrawable(Resources res) {
|
||||
return new AnimatedVectorDrawable(this, res, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Drawable newDrawable(Resources res, Theme theme) {
|
||||
return new AnimatedVectorDrawable(this, res, theme);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getChangingConfigurations() {
|
||||
return mChangingConfigurations;
|
||||
}
|
||||
}
|
||||
|
||||
private void setupAnimatorsForTarget(String name, Animator animator) {
|
||||
Object target = mAnimatedVectorState.mVectorDrawable.getTargetByName(name);
|
||||
animator.setTarget(target);
|
||||
mAnimatedVectorState.mAnimators.add(animator);
|
||||
if (DBG_ANIMATION_VECTOR_DRAWABLE) {
|
||||
Log.v(LOGTAG, "add animator for target " + name + " " + animator);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isRunning() {
|
||||
final ArrayList<Animator> animators = mAnimatedVectorState.mAnimators;
|
||||
final int size = animators.size();
|
||||
for (int i = 0; i < size; i++) {
|
||||
final Animator animator = animators.get(i);
|
||||
if (animator.isRunning()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void start() {
|
||||
final ArrayList<Animator> animators = mAnimatedVectorState.mAnimators;
|
||||
final int size = animators.size();
|
||||
for (int i = 0; i < size; i++) {
|
||||
final Animator animator = animators.get(i);
|
||||
if (animator.isPaused()) {
|
||||
animator.resume();
|
||||
} else if (!animator.isRunning()) {
|
||||
animator.start();
|
||||
}
|
||||
}
|
||||
invalidateSelf();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void stop() {
|
||||
final ArrayList<Animator> animators = mAnimatedVectorState.mAnimators;
|
||||
final int size = animators.size();
|
||||
for (int i = 0; i < size; i++) {
|
||||
final Animator animator = animators.get(i);
|
||||
animator.pause();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -209,7 +209,7 @@ public abstract class Drawable {
|
||||
* stored bounds of this drawable.
|
||||
*
|
||||
* @see #copyBounds()
|
||||
* @see #copyBounds(android.graphics.Rect)
|
||||
* @see #copyBounds(android.graphics.Rect)
|
||||
*/
|
||||
public final Rect getBounds() {
|
||||
if (mBounds == ZERO_BOUNDS_RECT) {
|
||||
@@ -328,8 +328,8 @@ public abstract class Drawable {
|
||||
* that want to support animated drawables.
|
||||
*
|
||||
* @param cb The client's Callback implementation.
|
||||
*
|
||||
* @see #getCallback()
|
||||
*
|
||||
* @see #getCallback()
|
||||
*/
|
||||
public final void setCallback(Callback cb) {
|
||||
mCallback = new WeakReference<Callback>(cb);
|
||||
@@ -338,10 +338,10 @@ public abstract class Drawable {
|
||||
/**
|
||||
* Return the current {@link Callback} implementation attached to this
|
||||
* Drawable.
|
||||
*
|
||||
*
|
||||
* @return A {@link Callback} instance or null if no callback was set.
|
||||
*
|
||||
* @see #setCallback(android.graphics.drawable.Drawable.Callback)
|
||||
*
|
||||
* @see #setCallback(android.graphics.drawable.Drawable.Callback)
|
||||
*/
|
||||
public Callback getCallback() {
|
||||
if (mCallback != null) {
|
||||
@@ -349,15 +349,15 @@ public abstract class Drawable {
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Use the current {@link Callback} implementation to have this Drawable
|
||||
* redrawn. Does nothing if there is no Callback attached to the
|
||||
* Drawable.
|
||||
*
|
||||
* @see Callback#invalidateDrawable
|
||||
* @see #getCallback()
|
||||
* @see #setCallback(android.graphics.drawable.Drawable.Callback)
|
||||
* @see #getCallback()
|
||||
* @see #setCallback(android.graphics.drawable.Drawable.Callback)
|
||||
*/
|
||||
public void invalidateSelf() {
|
||||
final Callback callback = getCallback();
|
||||
@@ -931,7 +931,7 @@ public abstract class Drawable {
|
||||
Rects only to drop them on the floor.
|
||||
*/
|
||||
Rect pad = new Rect();
|
||||
|
||||
|
||||
// Special stuff for compatibility mode: if the target density is not
|
||||
// the same as the display density, but the resource -is- the same as
|
||||
// the display density, then don't scale it down to the target density.
|
||||
@@ -1040,6 +1040,8 @@ public abstract class Drawable {
|
||||
drawable = new GradientDrawable();
|
||||
} else if (name.equals("vector")) {
|
||||
drawable = new VectorDrawable();
|
||||
} else if (name.equals("animated-vector")) {
|
||||
drawable = new AnimatedVectorDrawable();
|
||||
} else if (name.equals("scale")) {
|
||||
drawable = new ScaleDrawable();
|
||||
} else if (name.equals("clip")) {
|
||||
@@ -1047,7 +1049,7 @@ public abstract class Drawable {
|
||||
} else if (name.equals("rotate")) {
|
||||
drawable = new RotateDrawable();
|
||||
} else if (name.equals("animated-rotate")) {
|
||||
drawable = new AnimatedRotateDrawable();
|
||||
drawable = new AnimatedRotateDrawable();
|
||||
} else if (name.equals("animation-list")) {
|
||||
drawable = new AnimationDrawable();
|
||||
} else if (name.equals("inset")) {
|
||||
|
||||
@@ -27,6 +27,7 @@ import android.graphics.PathMeasure;
|
||||
import android.graphics.PixelFormat;
|
||||
import android.graphics.Rect;
|
||||
import android.graphics.Region;
|
||||
import android.util.ArrayMap;
|
||||
import android.util.AttributeSet;
|
||||
import android.util.Log;
|
||||
import android.util.Xml;
|
||||
@@ -40,7 +41,6 @@ import org.xmlpull.v1.XmlPullParserFactory;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.Stack;
|
||||
|
||||
/**
|
||||
@@ -135,6 +135,8 @@ public class VectorDrawable extends Drawable {
|
||||
|
||||
private final VectorDrawableState mVectorState;
|
||||
|
||||
private final ArrayMap<String, Object> mVGTargetsMap = new ArrayMap<String, Object>();
|
||||
|
||||
public VectorDrawable() {
|
||||
mVectorState = new VectorDrawableState(null);
|
||||
}
|
||||
@@ -147,6 +149,10 @@ public class VectorDrawable extends Drawable {
|
||||
}
|
||||
}
|
||||
|
||||
Object getTargetByName(String name) {
|
||||
return mVGTargetsMap.get(name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ConstantState getConstantState() {
|
||||
return mVectorState;
|
||||
@@ -161,6 +167,11 @@ public class VectorDrawable extends Drawable {
|
||||
canvas.restoreToCount(saveCount);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getAlpha() {
|
||||
return mVectorState.mVPathRenderer.getRootAlpha();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setAlpha(int alpha) {
|
||||
if (mVectorState.mVPathRenderer.getRootAlpha() != alpha) {
|
||||
@@ -302,6 +313,9 @@ public class VectorDrawable extends Drawable {
|
||||
final VPath path = new VPath();
|
||||
path.inflate(res, attrs, theme);
|
||||
currentGroup.add(path);
|
||||
if (path.getPathName() != null) {
|
||||
mVGTargetsMap.put(path.getPathName(), path);
|
||||
}
|
||||
noPathTag = false;
|
||||
} else if (SHAPE_SIZE.equals(tagName)) {
|
||||
pathRenderer.parseSize(res, attrs);
|
||||
@@ -314,6 +328,9 @@ public class VectorDrawable extends Drawable {
|
||||
newChildGroup.inflate(res, attrs, theme);
|
||||
currentGroup.mChildGroupList.add(newChildGroup);
|
||||
groupStack.push(newChildGroup);
|
||||
if (newChildGroup.getGroupName() != null) {
|
||||
mVGTargetsMap.put(newChildGroup.getGroupName(), newChildGroup);
|
||||
}
|
||||
noGroupTag = false;
|
||||
}
|
||||
} else if (eventType == XmlPullParser.END_TAG) {
|
||||
@@ -363,7 +380,7 @@ public class VectorDrawable extends Drawable {
|
||||
indent += " ";
|
||||
}
|
||||
// Print the current node
|
||||
Log.v(LOGTAG, indent + "current group is :" + currentGroup.getName()
|
||||
Log.v(LOGTAG, indent + "current group is :" + currentGroup.getGroupName()
|
||||
+ " rotation is " + currentGroup.mRotate);
|
||||
Log.v(LOGTAG, indent + "matrix is :" + currentGroup.getLocalMatrix().toString());
|
||||
// Then print all the children
|
||||
@@ -672,8 +689,7 @@ public class VectorDrawable extends Drawable {
|
||||
|
||||
}
|
||||
|
||||
private static class VGroup {
|
||||
private final HashMap<String, VPath> mVGPathMap = new HashMap<String, VPath>();
|
||||
static class VGroup {
|
||||
private final ArrayList<VPath> mPathList = new ArrayList<VPath>();
|
||||
private final ArrayList<VGroup> mChildGroupList = new ArrayList<VGroup>();
|
||||
|
||||
@@ -694,10 +710,98 @@ public class VectorDrawable extends Drawable {
|
||||
|
||||
private int[] mThemeAttrs;
|
||||
|
||||
private String mName = null;
|
||||
private String mGroupName = null;
|
||||
|
||||
public String getName() {
|
||||
return mName;
|
||||
/* Getter and Setter */
|
||||
public float getRotation() {
|
||||
return mRotate;
|
||||
}
|
||||
|
||||
public void setRotation(float rotation) {
|
||||
if (rotation != mRotate) {
|
||||
mRotate = rotation;
|
||||
updateLocalMatrix();
|
||||
}
|
||||
}
|
||||
|
||||
public float getPivotX() {
|
||||
return mPivotX;
|
||||
}
|
||||
|
||||
public void setPivotX(float pivotX) {
|
||||
if (pivotX != mPivotX) {
|
||||
mPivotX = pivotX;
|
||||
updateLocalMatrix();
|
||||
}
|
||||
}
|
||||
|
||||
public float getPivotY() {
|
||||
return mPivotY;
|
||||
}
|
||||
|
||||
public void setPivotY(float pivotY) {
|
||||
if (pivotY != mPivotY) {
|
||||
mPivotY = pivotY;
|
||||
updateLocalMatrix();
|
||||
}
|
||||
}
|
||||
|
||||
public float getScaleX() {
|
||||
return mScaleX;
|
||||
}
|
||||
|
||||
public void setScaleX(float scaleX) {
|
||||
if (scaleX != mScaleX) {
|
||||
mScaleX = scaleX;
|
||||
updateLocalMatrix();
|
||||
}
|
||||
}
|
||||
|
||||
public float getScaleY() {
|
||||
return mScaleY;
|
||||
}
|
||||
|
||||
public void setScaleY(float scaleY) {
|
||||
if (scaleY != mScaleY) {
|
||||
mScaleY = scaleY;
|
||||
updateLocalMatrix();
|
||||
}
|
||||
}
|
||||
|
||||
public float getTranslateX() {
|
||||
return mTranslateX;
|
||||
}
|
||||
|
||||
public void setTranslateX(float translateX) {
|
||||
if (translateX != mTranslateX) {
|
||||
mTranslateX = translateX;
|
||||
updateLocalMatrix();
|
||||
}
|
||||
}
|
||||
|
||||
public float getTranslateY() {
|
||||
return mTranslateY;
|
||||
}
|
||||
|
||||
public void setTranslateY(float translateY) {
|
||||
if (translateY != mTranslateY) {
|
||||
mTranslateY = translateY;
|
||||
updateLocalMatrix();
|
||||
}
|
||||
}
|
||||
|
||||
public float getAlpha() {
|
||||
return mGroupAlpha;
|
||||
}
|
||||
|
||||
public void setAlpha(float groupAlpha) {
|
||||
if (groupAlpha != mGroupAlpha) {
|
||||
mGroupAlpha = groupAlpha;
|
||||
}
|
||||
}
|
||||
|
||||
public String getGroupName() {
|
||||
return mGroupName;
|
||||
}
|
||||
|
||||
public Matrix getLocalMatrix() {
|
||||
@@ -705,8 +809,6 @@ public class VectorDrawable extends Drawable {
|
||||
}
|
||||
|
||||
public void add(VPath path) {
|
||||
String id = path.getID();
|
||||
mVGPathMap.put(id, path);
|
||||
mPathList.add(path);
|
||||
}
|
||||
|
||||
@@ -732,7 +834,7 @@ public class VectorDrawable extends Drawable {
|
||||
mGroupAlpha = a.getFloat(R.styleable.VectorDrawableGroup_alpha, mGroupAlpha);
|
||||
updateLocalMatrix();
|
||||
if (a.hasValue(R.styleable.VectorDrawableGroup_name)) {
|
||||
mName = a.getString(R.styleable.VectorDrawableGroup_name);
|
||||
mGroupName = a.getString(R.styleable.VectorDrawableGroup_name);
|
||||
}
|
||||
a.recycle();
|
||||
}
|
||||
@@ -774,7 +876,7 @@ public class VectorDrawable extends Drawable {
|
||||
}
|
||||
|
||||
if (themeAttrs == null || themeAttrs[R.styleable.VectorDrawableGroup_name] == 0) {
|
||||
mName = a.getString(R.styleable.VectorDrawableGroup_name);
|
||||
mGroupName = a.getString(R.styleable.VectorDrawableGroup_name);
|
||||
}
|
||||
|
||||
if (themeAttrs == null || themeAttrs[R.styleable.VectorDrawableGroup_alpha] == 0) {
|
||||
@@ -805,19 +907,15 @@ public class VectorDrawable extends Drawable {
|
||||
|
||||
}
|
||||
|
||||
private static class VPath {
|
||||
private static final int MAX_STATES = 10;
|
||||
|
||||
static class VPath {
|
||||
private int[] mThemeAttrs;
|
||||
|
||||
int mStrokeColor = 0;
|
||||
float mStrokeWidth = 0;
|
||||
float mStrokeOpacity = Float.NaN;
|
||||
|
||||
int mFillColor = Color.BLACK;
|
||||
int mFillRule;
|
||||
float mFillOpacity = Float.NaN;
|
||||
|
||||
float mTrimPathStart = 0;
|
||||
float mTrimPathEnd = 1;
|
||||
float mTrimPathOffset = 0;
|
||||
@@ -828,7 +926,7 @@ public class VectorDrawable extends Drawable {
|
||||
float mStrokeMiterlimit = 4;
|
||||
|
||||
private VNode[] mNode = null;
|
||||
private String mId;
|
||||
private String mPathName;
|
||||
|
||||
public VPath() {
|
||||
// Empty constructor.
|
||||
@@ -841,8 +939,8 @@ public class VectorDrawable extends Drawable {
|
||||
}
|
||||
}
|
||||
|
||||
public String getID() {
|
||||
return mId;
|
||||
public String getPathName() {
|
||||
return mPathName;
|
||||
}
|
||||
|
||||
private Paint.Cap getStrokeLineCap(int id, Paint.Cap defValue) {
|
||||
@@ -871,6 +969,71 @@ public class VectorDrawable extends Drawable {
|
||||
}
|
||||
}
|
||||
|
||||
/* Setters and Getters */
|
||||
int getStroke() {
|
||||
return mStrokeColor;
|
||||
}
|
||||
|
||||
void setStroke(int strokeColor) {
|
||||
mStrokeColor = strokeColor;
|
||||
}
|
||||
|
||||
float getStrokeWidth() {
|
||||
return mStrokeWidth;
|
||||
}
|
||||
|
||||
void setStrokeWidth(float strokeWidth) {
|
||||
mStrokeWidth = strokeWidth;
|
||||
}
|
||||
|
||||
float getStrokeOpacity() {
|
||||
return mStrokeOpacity;
|
||||
}
|
||||
|
||||
void setStrokeOpacity(float strokeOpacity) {
|
||||
mStrokeOpacity = strokeOpacity;
|
||||
}
|
||||
|
||||
int getFill() {
|
||||
return mFillColor;
|
||||
}
|
||||
|
||||
void setFill(int fillColor) {
|
||||
mFillColor = fillColor;
|
||||
}
|
||||
|
||||
float getFillOpacity() {
|
||||
return mFillOpacity;
|
||||
}
|
||||
|
||||
void setFillOpacity(float fillOpacity) {
|
||||
mFillOpacity = fillOpacity;
|
||||
}
|
||||
|
||||
float getTrimPathStart() {
|
||||
return mTrimPathStart;
|
||||
}
|
||||
|
||||
void setTrimPathStart(float trimPathStart) {
|
||||
mTrimPathStart = trimPathStart;
|
||||
}
|
||||
|
||||
float getTrimPathEnd() {
|
||||
return mTrimPathEnd;
|
||||
}
|
||||
|
||||
void setTrimPathEnd(float trimPathEnd) {
|
||||
mTrimPathEnd = trimPathEnd;
|
||||
}
|
||||
|
||||
float getTrimPathOffset() {
|
||||
return mTrimPathOffset;
|
||||
}
|
||||
|
||||
void setTrimPathOffset(float trimPathOffset) {
|
||||
mTrimPathOffset = trimPathOffset;
|
||||
}
|
||||
|
||||
public void inflate(Resources r, AttributeSet attrs, Theme theme) {
|
||||
final TypedArray a = obtainAttributes(r, theme, attrs, R.styleable.VectorDrawablePath);
|
||||
final int[] themeAttrs = a.extractThemeAttrs();
|
||||
@@ -883,7 +1046,7 @@ public class VectorDrawable extends Drawable {
|
||||
}
|
||||
|
||||
if (themeAttrs == null || themeAttrs[R.styleable.VectorDrawablePath_name] == 0) {
|
||||
mId = a.getString(R.styleable.VectorDrawablePath_name);
|
||||
mPathName = a.getString(R.styleable.VectorDrawablePath_name);
|
||||
}
|
||||
|
||||
if (themeAttrs == null || themeAttrs[R.styleable.VectorDrawablePath_pathData] == 0) {
|
||||
@@ -966,7 +1129,7 @@ public class VectorDrawable extends Drawable {
|
||||
mClip = a.getBoolean(R.styleable.VectorDrawablePath_clipToPath, mClip);
|
||||
|
||||
if (a.hasValue(R.styleable.VectorDrawablePath_name)) {
|
||||
mId = a.getString(R.styleable.VectorDrawablePath_name);
|
||||
mPathName = a.getString(R.styleable.VectorDrawablePath_name);
|
||||
}
|
||||
|
||||
if (a.hasValue(R.styleable.VectorDrawablePath_pathData)) {
|
||||
|
||||
@@ -17,13 +17,13 @@
|
||||
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="com.android.test.dynamic" >
|
||||
|
||||
<uses-sdk android:minSdkVersion="20" />
|
||||
|
||||
<application
|
||||
android:hardwareAccelerated="true"
|
||||
android:label="vector" >
|
||||
|
||||
<activity
|
||||
<activity
|
||||
android:name="VectorDrawablePerformance"
|
||||
android:label="Vector Performance" >
|
||||
<intent-filter>
|
||||
@@ -31,13 +31,13 @@
|
||||
|
||||
<category android:name="com.android.test.dynamic.TEST" />
|
||||
</intent-filter>
|
||||
|
||||
</activity>
|
||||
<activity
|
||||
android:name="VectorDrawableAnimation"
|
||||
android:label="VectorTestAnimation" >
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN" />
|
||||
|
||||
<category android:name="com.android.test.dynamic.TEST" />
|
||||
</intent-filter>
|
||||
</activity>
|
||||
@@ -51,6 +51,15 @@
|
||||
<category android:name="android.intent.category.LAUNCHER" />
|
||||
</intent-filter>
|
||||
</activity>
|
||||
<activity
|
||||
android:name="AnimatedVectorDrawableTest"
|
||||
android:label="AnimatedVectorDrawableTest" >
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN" />
|
||||
|
||||
<category android:name="com.android.test.dynamic.TEST" />
|
||||
</intent-filter>
|
||||
</activity>
|
||||
<activity
|
||||
android:name="VectorDrawable01"
|
||||
android:label="VectorTest1" >
|
||||
@@ -68,7 +77,6 @@
|
||||
|
||||
<category android:name="com.android.test.dynamic.TEST" />
|
||||
</intent-filter>
|
||||
|
||||
</activity>
|
||||
<activity
|
||||
android:name="VectorDrawableStaticPerf"
|
||||
@@ -78,9 +86,7 @@
|
||||
|
||||
<category android:name="com.android.test.dynamic.TEST" />
|
||||
</intent-filter>
|
||||
|
||||
</activity>
|
||||
|
||||
<activity
|
||||
android:name="VectorCheckbox"
|
||||
android:label="On a Checkbox" >
|
||||
@@ -89,7 +95,6 @@
|
||||
|
||||
<category android:name="com.android.test.dynamic.TEST" />
|
||||
</intent-filter>
|
||||
|
||||
</activity>
|
||||
<activity
|
||||
android:name="VectorPathChecking"
|
||||
@@ -99,7 +104,6 @@
|
||||
|
||||
<category android:name="com.android.test.dynamic.TEST" />
|
||||
</intent-filter>
|
||||
|
||||
</activity>
|
||||
</application>
|
||||
|
||||
|
||||
35
tests/VectorDrawableTest/res/anim/trim_path_animation01.xml
Normal file
35
tests/VectorDrawableTest/res/anim/trim_path_animation01.xml
Normal file
@@ -0,0 +1,35 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
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.
|
||||
-->
|
||||
|
||||
<set xmlns:android="http://schemas.android.com/apk/res/android" >
|
||||
|
||||
<set android:ordering="sequentially" >
|
||||
<objectAnimator
|
||||
android:duration="5000"
|
||||
android:propertyName="trimPathEnd"
|
||||
android:valueFrom="0"
|
||||
android:valueTo="1"
|
||||
android:valueType="floatType" />
|
||||
<objectAnimator
|
||||
android:duration="5000"
|
||||
android:propertyName="trimPathEnd"
|
||||
android:valueFrom="1"
|
||||
android:valueTo="0"
|
||||
android:valueType="floatType" />
|
||||
</set>
|
||||
|
||||
</set>
|
||||
26
tests/VectorDrawableTest/res/anim/trim_path_animation02.xml
Normal file
26
tests/VectorDrawableTest/res/anim/trim_path_animation02.xml
Normal file
@@ -0,0 +1,26 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
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.
|
||||
-->
|
||||
|
||||
<set xmlns:android="http://schemas.android.com/apk/res/android" >
|
||||
|
||||
<objectAnimator
|
||||
android:duration="5000"
|
||||
android:propertyName="fill"
|
||||
android:valueFrom="#FF000000"
|
||||
android:valueTo="#FFFF0000"/>
|
||||
|
||||
</set>
|
||||
26
tests/VectorDrawableTest/res/anim/trim_path_animation03.xml
Normal file
26
tests/VectorDrawableTest/res/anim/trim_path_animation03.xml
Normal file
@@ -0,0 +1,26 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
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.
|
||||
-->
|
||||
|
||||
<set xmlns:android="http://schemas.android.com/apk/res/android" >
|
||||
|
||||
<objectAnimator
|
||||
android:duration="6000"
|
||||
android:propertyName="rotation"
|
||||
android:valueFrom="0"
|
||||
android:valueTo="360"/>
|
||||
|
||||
</set>
|
||||
26
tests/VectorDrawableTest/res/anim/trim_path_animation04.xml
Normal file
26
tests/VectorDrawableTest/res/anim/trim_path_animation04.xml
Normal file
@@ -0,0 +1,26 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
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.
|
||||
-->
|
||||
|
||||
<set xmlns:android="http://schemas.android.com/apk/res/android" >
|
||||
|
||||
<objectAnimator
|
||||
android:duration="9000"
|
||||
android:propertyName="rotation"
|
||||
android:valueFrom="0"
|
||||
android:valueTo="360"/>
|
||||
|
||||
</set>
|
||||
@@ -0,0 +1,36 @@
|
||||
<!--
|
||||
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.
|
||||
-->
|
||||
<animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:drawable="@drawable/vector_drawable12" >
|
||||
|
||||
<target
|
||||
android:name="pie1"
|
||||
android:animation="@anim/trim_path_animation01" />
|
||||
<target
|
||||
android:name="v"
|
||||
android:animation="@anim/trim_path_animation02" />
|
||||
|
||||
<target
|
||||
android:name="rotationGroup"
|
||||
android:animation="@anim/trim_path_animation03" />
|
||||
<target
|
||||
android:name="rotationGroup3"
|
||||
android:animation="@anim/trim_path_animation03" />
|
||||
<target
|
||||
android:name="rotationGroupBlue"
|
||||
android:animation="@anim/trim_path_animation03" />
|
||||
|
||||
</animated-vector>
|
||||
@@ -23,11 +23,15 @@
|
||||
android:viewportHeight="600"
|
||||
android:viewportWidth="600" />
|
||||
|
||||
<group>
|
||||
<group
|
||||
android:name="rotationGroup"
|
||||
android:pivotX="300.0"
|
||||
android:pivotY="300.0"
|
||||
android:rotation="45.0" >
|
||||
<path
|
||||
android:name="pie1"
|
||||
android:pathData="M300,70 a230,230 0 1,0 1,0 z"
|
||||
android:fill="#00000000"
|
||||
android:pathData="M300,70 a230,230 0 1,0 1,0 z"
|
||||
android:stroke="#FF00FF00"
|
||||
android:strokeWidth="70"
|
||||
android:trimPathEnd=".75"
|
||||
@@ -36,7 +40,66 @@
|
||||
<path
|
||||
android:name="v"
|
||||
android:fill="#FF00FF00"
|
||||
android:pathData="M300,70 l 0,-70 70,70 -70,70z"/>
|
||||
android:pathData="M300,70 l 0,-70 70,70 -70,70z" />
|
||||
|
||||
<group
|
||||
android:name="translateToCenterGroup"
|
||||
android:rotation="0.0"
|
||||
android:translateX="200.0"
|
||||
android:translateY="200.0" >
|
||||
<path
|
||||
android:name="twoLines"
|
||||
android:pathData="@string/twoLinePathData"
|
||||
android:stroke="#FFFF0000"
|
||||
android:strokeWidth="20" />
|
||||
|
||||
<group
|
||||
android:name="rotationGroup2"
|
||||
android:pivotX="0.0"
|
||||
android:pivotY="0.0"
|
||||
android:rotation="-45.0" >
|
||||
<path
|
||||
android:name="twoLines1"
|
||||
android:pathData="@string/twoLinePathData"
|
||||
android:stroke="#FF00FF00"
|
||||
android:strokeWidth="20" />
|
||||
|
||||
<group
|
||||
android:name="translateGroupHalf"
|
||||
android:translateX="65.0"
|
||||
android:translateY="80.0" >
|
||||
<group
|
||||
android:name="rotationGroup3"
|
||||
android:pivotX="-65.0"
|
||||
android:pivotY="-80.0"
|
||||
android:rotation="-45.0" >
|
||||
<path
|
||||
android:name="twoLines2"
|
||||
android:fill="#FF00FF00"
|
||||
android:pathData="@string/twoLinePathData"
|
||||
android:stroke="#FF00FF00"
|
||||
android:strokeWidth="20" />
|
||||
|
||||
<group
|
||||
android:name="translateGroup"
|
||||
android:translateX="65.0"
|
||||
android:translateY="80.0" >
|
||||
<group
|
||||
android:name="rotationGroupBlue"
|
||||
android:pivotX="-65.0"
|
||||
android:pivotY="-80.0"
|
||||
android:rotation="-45.0" >
|
||||
<path
|
||||
android:name="twoLines3"
|
||||
android:pathData="@string/twoLinePathData"
|
||||
android:stroke="#FF0000FF"
|
||||
android:strokeWidth="20" />
|
||||
</group>
|
||||
</group>
|
||||
</group>
|
||||
</group>
|
||||
</group>
|
||||
</group>
|
||||
</group>
|
||||
|
||||
</vector>
|
||||
@@ -0,0 +1,42 @@
|
||||
/*
|
||||
* 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 com.android.test.dynamic;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.graphics.drawable.AnimatedVectorDrawable;
|
||||
import android.os.Bundle;
|
||||
import android.view.View;
|
||||
import android.widget.Button;
|
||||
|
||||
public class AnimatedVectorDrawableTest extends Activity {
|
||||
private static final String LOGCAT = "VectorDrawableAnimationTest";
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
Button button = new Button(this);
|
||||
button.setBackgroundResource(R.drawable.animation_vector_drawable01);
|
||||
button.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
AnimatedVectorDrawable frameAnimation = (AnimatedVectorDrawable) v.getBackground();
|
||||
frameAnimation.start();
|
||||
}
|
||||
});
|
||||
|
||||
setContentView(button);
|
||||
}
|
||||
}
|
||||
@@ -14,6 +14,7 @@
|
||||
|
||||
package com.android.test.dynamic;
|
||||
|
||||
import android.animation.ValueAnimator;
|
||||
import android.app.Activity;
|
||||
import android.graphics.drawable.AnimationDrawable;
|
||||
import android.os.Bundle;
|
||||
@@ -27,7 +28,7 @@ public class VectorDrawableAnimation extends Activity {
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
Button button = new Button(this);
|
||||
final Button button = new Button(this);
|
||||
button.setBackgroundResource(R.drawable.animation_drawable_vector);
|
||||
|
||||
button.setOnClickListener(new View.OnClickListener() {
|
||||
|
||||
Reference in New Issue
Block a user