Skip to content

Commit

Permalink
Animators defined in XMLs should work with Build Tools 22
Browse files Browse the repository at this point in the history
Problem: Build Tools 22 removes attributes targeted to higher
versions of Android from xml file, copying the original
file to an appropriate bucket. On lower versions of
Android (f.e. 9) NineOldAndroids can't access such
attributes (as they are now in animator-vXX bucket) and crashes.

Solution: let's use our own custom attributes instead of
Android attributes. All XMLs defining animators should be changed -
project namespace should be used instead of Android one.

Fixes JakeWharton#80
  • Loading branch information
serso committed Apr 11, 2015
1 parent d582f0e commit 0f21c44
Show file tree
Hide file tree
Showing 6 changed files with 85 additions and 82 deletions.
32 changes: 32 additions & 0 deletions library/res/values/attrs.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<!--
Attributes similar to attributes from Android animator framework. Copied to be used on any
version of Android without having build problems described here https://github.com/JakeWharton/NineOldAndroids/issues/80
-->
<declare-styleable name="PropertyAnimator">
<attr name="propertyName" format="string" />
</declare-styleable>
<declare-styleable name="AnimatorSet">
<attr name="ordering" format="enum">
<enum name="together" value="0" />
<enum name="sequentially" value="1" />
</attr>
</declare-styleable>
<declare-styleable name="Animator">
<attr name="interpolator" format="reference" />
<attr name="duration" format="integer" />
<attr name="startOffset" format="integer" />
<attr name="repeatCount" format="integer" />
<attr name="repeatMode" format="enum">
<enum name="restart" value="1" />
<enum name="reverse" value="2" />
</attr>
<attr name="valueFrom" format="float|integer|color" />
<attr name="valueTo" format="float|integer|color" />
<attr name="valueType" format="enum">
<enum name="floatType" value="0" />
<enum name="intType" value="1" />
</attr>
</declare-styleable>
</resources>
63 changes: 17 additions & 46 deletions library/src/com/nineoldandroids/animation/AnimatorInflater.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,14 @@

import android.content.Context;
import android.content.res.Resources;
import android.content.res.Resources.NotFoundException;
import android.content.res.TypedArray;
import android.content.res.XmlResourceParser;
import android.content.res.Resources.NotFoundException;
import android.util.AttributeSet;
import android.util.TypedValue;
import android.util.Xml;
import android.view.animation.AnimationUtils;
import com.nineoldandroids.R;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;

Expand All @@ -40,35 +41,6 @@
* <em>something</em> file.)
*/
public class AnimatorInflater {
private static final int[] AnimatorSet = new int[] {
/* 0 */ android.R.attr.ordering,
};
private static final int AnimatorSet_ordering = 0;

private static final int[] PropertyAnimator = new int[] {
/* 0 */ android.R.attr.propertyName,
};
private static final int PropertyAnimator_propertyName = 0;

private static final int[] Animator = new int[] {
/* 0 */ android.R.attr.interpolator,
/* 1 */ android.R.attr.duration,
/* 2 */ android.R.attr.startOffset,
/* 3 */ android.R.attr.repeatCount,
/* 4 */ android.R.attr.repeatMode,
/* 5 */ android.R.attr.valueFrom,
/* 6 */ android.R.attr.valueTo,
/* 7 */ android.R.attr.valueType,
};
private static final int Animator_interpolator = 0;
private static final int Animator_duration = 1;
private static final int Animator_startOffset = 2;
private static final int Animator_repeatCount = 3;
private static final int Animator_repeatMode = 4;
private static final int Animator_valueFrom = 5;
private static final int Animator_valueTo = 6;
private static final int Animator_valueType = 7;

/**
* These flags are used when parsing AnimatorSet objects
*/
Expand Down Expand Up @@ -147,11 +119,10 @@ private static Animator createAnimatorFromXml(Context c, XmlPullParser parser,
anim = loadAnimator(c, attrs, null);
} else if (name.equals("set")) {
anim = new AnimatorSet();
TypedArray a = c.obtainStyledAttributes(attrs,
/*com.android.internal.R.styleable.*/AnimatorSet);
TypedArray a = c.obtainStyledAttributes(attrs, R.styleable.AnimatorSet);

TypedValue orderingValue = new TypedValue();
a.getValue(/*com.android.internal.R.styleable.*/AnimatorSet_ordering, orderingValue);
a.getValue(R.styleable.AnimatorSet_ordering, orderingValue);
int ordering = orderingValue.type == TypedValue.TYPE_INT_DEC ? orderingValue.data : TOGETHER;

createAnimatorFromXml(c, parser, attrs, (AnimatorSet) anim, ordering);
Expand Down Expand Up @@ -192,9 +163,9 @@ private static ObjectAnimator loadObjectAnimator(Context context, AttributeSet a
loadAnimator(context, attrs, anim);

TypedArray a =
context.obtainStyledAttributes(attrs, /*com.android.internal.R.styleable.*/PropertyAnimator);
context.obtainStyledAttributes(attrs, R.styleable.PropertyAnimator);

String propertyName = a.getString(/*com.android.internal.R.styleable.*/PropertyAnimator_propertyName);
String propertyName = a.getString(R.styleable.PropertyAnimator_propertyName);

anim.setPropertyName(propertyName);

Expand All @@ -214,22 +185,22 @@ private static ValueAnimator loadAnimator(Context context, AttributeSet attrs, V
throws NotFoundException {

TypedArray a =
context.obtainStyledAttributes(attrs, /*com.android.internal.R.styleable.*/Animator);
context.obtainStyledAttributes(attrs, R.styleable.Animator);

long duration = a.getInt(/*com.android.internal.R.styleable.*/Animator_duration, 0);
long duration = a.getInt(R.styleable.Animator_duration, 0);

long startDelay = a.getInt(/*com.android.internal.R.styleable.*/Animator_startOffset, 0);
long startDelay = a.getInt(R.styleable.Animator_startOffset, 0);

int valueType = a.getInt(/*com.android.internal.R.styleable.*/Animator_valueType,
int valueType = a.getInt(R.styleable.Animator_valueType,
VALUE_TYPE_FLOAT);

if (anim == null) {
anim = new ValueAnimator();
}
//TypeEvaluator evaluator = null;

int valueFromIndex = /*com.android.internal.R.styleable.*/Animator_valueFrom;
int valueToIndex = /*com.android.internal.R.styleable.*/Animator_valueTo;
int valueFromIndex = R.styleable.Animator_valueFrom;
int valueToIndex = R.styleable.Animator_valueTo;

boolean getFloats = (valueType == VALUE_TYPE_FLOAT);

Expand Down Expand Up @@ -319,21 +290,21 @@ private static ValueAnimator loadAnimator(Context context, AttributeSet attrs, V
anim.setDuration(duration);
anim.setStartDelay(startDelay);

if (a.hasValue(/*com.android.internal.R.styleable.*/Animator_repeatCount)) {
if (a.hasValue(R.styleable.Animator_repeatCount)) {
anim.setRepeatCount(
a.getInt(/*com.android.internal.R.styleable.*/Animator_repeatCount, 0));
a.getInt(R.styleable.Animator_repeatCount, 0));
}
if (a.hasValue(/*com.android.internal.R.styleable.*/Animator_repeatMode)) {
if (a.hasValue(R.styleable.Animator_repeatMode)) {
anim.setRepeatMode(
a.getInt(/*com.android.internal.R.styleable.*/Animator_repeatMode,
a.getInt(R.styleable.Animator_repeatMode,
ValueAnimator.RESTART));
}
//if (evaluator != null) {
// anim.setEvaluator(evaluator);
//}

final int resID =
a.getResourceId(/*com.android.internal.R.styleable.*/Animator_interpolator, 0);
a.getResourceId(R.styleable.Animator_interpolator, 0);
if (resID > 0) {
anim.setInterpolator(AnimationUtils.loadInterpolator(context, resID));
}
Expand Down
14 changes: 7 additions & 7 deletions sample/res/anim/animator.xml
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,10 @@
limitations under the License.
-->

<animator xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="1000"
android:valueFrom="1"
android:valueTo="0"
android:valueType="floatType"
android:repeatCount="1"
android:repeatMode="reverse"/>
<animator xmlns:noa="http://schemas.android.com/apk/res-auto"
noa:duration="1000"
noa:valueFrom="1"
noa:valueTo="0"
noa:valueType="floatType"
noa:repeatCount="1"
noa:repeatMode="reverse"/>
30 changes: 15 additions & 15 deletions sample/res/anim/animator_set.xml
Original file line number Diff line number Diff line change
Expand Up @@ -14,19 +14,19 @@
limitations under the License.
-->

<set>
<objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="1000"
android:valueTo="200"
android:valueType="floatType"
android:propertyName="x"
android:repeatCount="1"
android:repeatMode="reverse"/>
<objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="1000"
android:valueTo="400"
android:valueType="floatType"
android:propertyName="y"
android:repeatCount="1"
android:repeatMode="reverse"/>
<set xmlns:noa="http://schemas.android.com/apk/res-auto">
<objectAnimator
noa:duration="1000"
noa:valueTo="200"
noa:valueType="floatType"
noa:propertyName="x"
noa:repeatCount="1"
noa:repeatMode="reverse"/>
<objectAnimator
noa:duration="1000"
noa:valueTo="400"
noa:valueType="floatType"
noa:propertyName="y"
noa:repeatCount="1"
noa:repeatMode="reverse"/>
</set>
14 changes: 7 additions & 7 deletions sample/res/anim/color_animator.xml
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,10 @@
limitations under the License.
-->

<objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="1000"
android:valueFrom="#0f0"
android:valueTo="#00ffff"
android:propertyName="color"
android:repeatCount="1"
android:repeatMode="reverse"/>
<objectAnimator xmlns:noa="http://schemas.android.com/apk/res-auto"
noa:duration="1000"
noa:valueFrom="#0f0"
noa:valueTo="#00ffff"
noa:propertyName="color"
noa:repeatCount="1"
noa:repeatMode="reverse"/>
14 changes: 7 additions & 7 deletions sample/res/anim/object_animator.xml
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,10 @@
limitations under the License.
-->

<objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="1000"
android:valueTo="200"
android:valueType="floatType"
android:propertyName="y"
android:repeatCount="1"
android:repeatMode="reverse"/>
<objectAnimator xmlns:noa="http://schemas.android.com/apk/res-auto"
noa:duration="1000"
noa:valueTo="200"
noa:valueType="floatType"
noa:propertyName="y"
noa:repeatCount="1"
noa:repeatMode="reverse"/>

0 comments on commit 0f21c44

Please sign in to comment.