Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit d51d368f authored by Chet Haase's avatar Chet Haase
Browse files

Change animator xml importing to use new inflater class

Change-Id: I97225ee9868f4dcce5e4c1ba55e16414eb6c0464
parent 17b4d9ea
Loading
Loading
Loading
Loading
+47 −25
Original line number Diff line number Diff line
@@ -19966,6 +19966,40 @@
</parameter>
</method>
</interface>
<class name="AnimatableInflater"
 extends="java.lang.Object"
 abstract="false"
 static="false"
 final="false"
 deprecated="not deprecated"
 visibility="public"
>
<constructor name="AnimatableInflater"
 type="android.animation.AnimatableInflater"
 static="false"
 final="false"
 deprecated="not deprecated"
 visibility="public"
>
</constructor>
<method name="loadAnimatable"
 return="android.animation.Animatable"
 abstract="false"
 native="false"
 synchronized="false"
 static="true"
 final="false"
 deprecated="not deprecated"
 visibility="public"
>
<parameter name="context" type="android.content.Context">
</parameter>
<parameter name="id" type="int">
</parameter>
<exception name="Resources.NotFoundException" type="android.content.res.Resources.NotFoundException">
</exception>
</method>
</class>
<class name="AnimatableListenerAdapter"
 extends="java.lang.Object"
 abstract="true"
@@ -20052,10 +20086,6 @@
 deprecated="not deprecated"
 visibility="public"
>
<parameter name="context" type="android.content.Context">
</parameter>
<parameter name="attrs" type="android.util.AttributeSet">
</parameter>
</constructor>
<constructor name="Animator"
 type="android.animation.Animator"
@@ -20231,6 +20261,19 @@
<parameter name="playTime" type="long">
</parameter>
</method>
<method name="setDuration"
 return="void"
 abstract="false"
 native="false"
 synchronized="false"
 static="false"
 final="false"
 deprecated="not deprecated"
 visibility="public"
>
<parameter name="duration" type="long">
</parameter>
</method>
<method name="setEvaluator"
 return="void"
 abstract="false"
@@ -20653,10 +20696,6 @@
 deprecated="not deprecated"
 visibility="public"
>
<parameter name="context" type="android.content.Context">
</parameter>
<parameter name="attrs" type="android.util.AttributeSet">
</parameter>
</constructor>
<constructor name="PropertyAnimator"
 type="android.animation.PropertyAnimator"
@@ -205789,23 +205828,6 @@
<exception name="Resources.NotFoundException" type="android.content.res.Resources.NotFoundException">
</exception>
</method>
<method name="loadAnimator"
 return="android.animation.Animatable"
 abstract="false"
 native="false"
 synchronized="false"
 static="true"
 final="false"
 deprecated="not deprecated"
 visibility="public"
>
<parameter name="context" type="android.content.Context">
</parameter>
<parameter name="id" type="int">
</parameter>
<exception name="Resources.NotFoundException" type="android.content.res.Resources.NotFoundException">
</exception>
</method>
<method name="loadInterpolator"
 return="android.view.animation.Interpolator"
 abstract="false"
+269 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2010 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.animation;

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

import java.io.IOException;
import java.util.ArrayList;

/**
 * This class is used to instantiate menu XML files into Animatable objects.
 * <p>
 * For performance reasons, menu inflation relies heavily on pre-processing of
 * XML files that is done at build time. Therefore, it is not currently possible
 * to use MenuInflater with an XmlPullParser over a plain XML file at runtime;
 * it only works with an XmlPullParser returned from a compiled resource (R.
 * <em>something</em> file.)
 */
public class AnimatableInflater {

    /**
     * These flags are used when parsing Sequencer objects
     */
    private static final int TOGETHER = 0;
    private static final int SEQUENTIALLY = 1;

    /**
     * Enum values used in XML attributes to indicate the value for mValueType
     */
    private static final int VALUE_TYPE_FLOAT       = 0;
    private static final int VALUE_TYPE_INT         = 1;
    private static final int VALUE_TYPE_DOUBLE      = 2;
    private static final int VALUE_TYPE_COLOR       = 3;
    private static final int VALUE_TYPE_CUSTOM      = 4;

    /**
     * Loads an {@link Animatable} object from a resource
     *
     * @param context Application context used to access resources
     * @param id The resource id of the animation to load
     * @return The animatable object reference by the specified id
     * @throws android.content.res.Resources.NotFoundException when the animation cannot be loaded
     */
    public static Animatable loadAnimatable(Context context, int id)
            throws NotFoundException {

        XmlResourceParser parser = null;
        try {
            parser = context.getResources().getAnimation(id);
            return createAnimatableFromXml(context, parser);
        } catch (XmlPullParserException ex) {
            Resources.NotFoundException rnf =
                    new Resources.NotFoundException("Can't load animation resource ID #0x" +
                    Integer.toHexString(id));
            rnf.initCause(ex);
            throw rnf;
        } catch (IOException ex) {
            Resources.NotFoundException rnf =
                    new Resources.NotFoundException("Can't load animation resource ID #0x" +
                    Integer.toHexString(id));
            rnf.initCause(ex);
            throw rnf;
        } finally {
            if (parser != null) parser.close();
        }
    }

    private static Animatable createAnimatableFromXml(Context c, XmlPullParser parser)
            throws XmlPullParserException, IOException {

        return createAnimatableFromXml(c, parser, Xml.asAttributeSet(parser), null, 0);
    }

    private static Animatable createAnimatableFromXml(Context c, XmlPullParser parser,
            AttributeSet attrs, Sequencer parent, int sequenceOrdering)
            throws XmlPullParserException, IOException {

        Animatable anim = null;
        ArrayList<Animatable> 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("property")) {
                anim = loadPropertyAnimator(c, attrs);
            } else if (name.equals("animator")) {
                anim = loadAnimator(c, attrs, null);
            } else if (name.equals("sequencer")) {
                anim = new Sequencer();
                TypedArray a = c.obtainStyledAttributes(attrs,
                        com.android.internal.R.styleable.Sequencer);
                int ordering = a.getInt(com.android.internal.R.styleable.Sequencer_ordering,
                        TOGETHER);
                createAnimatableFromXml(c, parser, attrs, (Sequencer) anim,  ordering);
                a.recycle();
            } else {
                throw new RuntimeException("Unknown animator name: " + parser.getName());
            }

            if (parent != null) {
                if (childAnims == null) {
                    childAnims = new ArrayList<Animatable>();
                }
                childAnims.add(anim);
            }
        }
        if (parent != null && childAnims != null) {
            Animatable[] animsArray = new Animatable[childAnims.size()];
            int index = 0;
            for (Animatable a : childAnims) {
                animsArray[index++] = a;
            }
            if (sequenceOrdering == TOGETHER) {
                parent.playTogether(animsArray);
            } else {
                parent.playSequentially(animsArray);
            }
        }

        return anim;

    }

    private static PropertyAnimator loadPropertyAnimator(Context context, AttributeSet attrs)
            throws NotFoundException {

        PropertyAnimator anim = new PropertyAnimator();

        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 Animator loadAnimator(Context context, AttributeSet attrs, Animator anim)
            throws NotFoundException {

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

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

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

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

        Object valueFrom = null;
        Object valueTo = null;
        TypeEvaluator evaluator = null;

        switch (valueType) {
            case VALUE_TYPE_FLOAT:
                if (a.hasValue(com.android.internal.R.styleable.Animator_valueFrom)) {
                    valueFrom = a.getFloat(com.android.internal.R.styleable.Animator_valueFrom, 0f);
                }
                if (a.hasValue(com.android.internal.R.styleable.Animator_valueTo)) {
                    valueTo = a.getFloat(com.android.internal.R.styleable.Animator_valueTo, 0f);
                }
                break;
            case VALUE_TYPE_COLOR:
                evaluator = new RGBEvaluator();
                // fall through to pick up values
            case VALUE_TYPE_INT:
                if (a.hasValue(com.android.internal.R.styleable.Animator_valueFrom)) {
                    valueFrom = a.getInteger(com.android.internal.R.styleable.Animator_valueFrom, 0);
                }
                if (a.hasValue(com.android.internal.R.styleable.Animator_valueTo)) {
                    valueTo = a.getInteger(com.android.internal.R.styleable.Animator_valueTo, 0);
                }
                break;
            case VALUE_TYPE_DOUBLE:
                if (a.hasValue(com.android.internal.R.styleable.Animator_valueFrom)) {
                    valueFrom = (Double)((Float)(a.getFloat(com.android.internal.R.styleable.Animator_valueFrom, 0f))).doubleValue();
                }
                if (a.hasValue(com.android.internal.R.styleable.Animator_valueTo)) {
                    valueTo = (Double)((Float)a.getFloat(com.android.internal.R.styleable.Animator_valueTo, 0f)).doubleValue();
                }
                break;
            case VALUE_TYPE_CUSTOM:
                // TODO: How to get an 'Object' value?
                if (a.hasValue(com.android.internal.R.styleable.Animator_valueFrom)) {
                    valueFrom = a.getFloat(com.android.internal.R.styleable.Animator_valueFrom, 0f);
                }
                if (a.hasValue(com.android.internal.R.styleable.Animator_valueTo)) {
                    valueTo = a.getFloat(com.android.internal.R.styleable.Animator_valueTo, 0f);
                }
                break;
        }

        if (anim == null) {
            anim = new Animator(duration, valueFrom, valueTo);
        } else {
            anim.setDuration(duration);
            anim.setValues(valueFrom, valueTo);
        }

        anim.setStartDelay(startDelay);

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

        final int resID =
                a.getResourceId(com.android.internal.R.styleable.Animator_interpolator, 0);
        if (resID > 0) {
            anim.setInterpolator(AnimationUtils.loadInterpolator(context, resID));
        }
        a.recycle();

        return anim;
    }
}
+24 −93
Original line number Diff line number Diff line
@@ -17,11 +17,9 @@
package android.animation;

import android.content.Context;
import android.content.res.TypedArray;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.util.AttributeSet;
import android.view.animation.AccelerateDecelerateInterpolator;
import android.view.animation.AnimationUtils;
import android.view.animation.Interpolator;
@@ -69,15 +67,6 @@ public class Animator<T> extends Animatable {
    private static final int ENDED      = 3; // end() called - need to end it
    private static final int SEEKED     = 4; // Seeked to some time value

    /**
     * Enum values used in XML attributes to indicate the value for mValueType
     */
    private static final int VALUE_TYPE_FLOAT       = 0;
    private static final int VALUE_TYPE_INT         = 1;
    private static final int VALUE_TYPE_DOUBLE      = 2;
    private static final int VALUE_TYPE_COLOR       = 3;
    private static final int VALUE_TYPE_CUSTOM      = 4;

    /**
     * Internal variables
     * NOTE: This object implements the clone() method, making a deep copy of any referenced
@@ -208,11 +197,6 @@ public class Animator<T> extends Animatable {
     */
    HashMap<String, PropertyValuesHolder> mValuesMap;

    /**
     * The type of the values, as determined by the valueFrom/valueTo properties.
     */
    Class mValueType;

    /**
     * Public constants
     */
@@ -234,76 +218,13 @@ public class Animator<T> extends Animatable {
    public static final int INFINITE = -1;

    /**
     * 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
     * Creates a new Animator object. This default constructor is primarily for
     * use internally; the other constructors which take parameters are more generally
     * useful.
     */
    public Animator(Context context, AttributeSet attrs) {
        TypedArray a =
                context.obtainStyledAttributes(attrs, com.android.internal.R.styleable.Animator);

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

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

        final int resID =
                a.getResourceId(com.android.internal.R.styleable.Animator_interpolator, 0);
        if (resID > 0) {
            setInterpolator(AnimationUtils.loadInterpolator(context, resID));
        }
        int valueType = a.getInt(com.android.internal.R.styleable.Animator_valueType,
                VALUE_TYPE_FLOAT);

        Object valueFrom = null;
        Object valueTo = null;

        switch (valueType) {
            case VALUE_TYPE_FLOAT:
                valueFrom = a.getFloat(com.android.internal.R.styleable.Animator_valueFrom, 0f);
                valueTo = a.getFloat(com.android.internal.R.styleable.Animator_valueTo, 0f);
                mValueType = float.class;
                break;
            case VALUE_TYPE_INT:
                valueFrom = a.getInt(com.android.internal.R.styleable.Animator_valueFrom, 0);
                valueTo = a.getInt(com.android.internal.R.styleable.Animator_valueTo, 0);
                mValueType = int.class;
                break;
            case VALUE_TYPE_DOUBLE:
                valueFrom = (double)
                        a.getFloat(com.android.internal.R.styleable.Animator_valueFrom, 0f);
                valueTo = (double)
                        a.getFloat(com.android.internal.R.styleable.Animator_valueTo, 0f);
                mValueType = double.class;
                break;
            case VALUE_TYPE_COLOR:
                valueFrom = a.getInt(com.android.internal.R.styleable.Animator_valueFrom, 0);
                valueTo = a.getInt(com.android.internal.R.styleable.Animator_valueTo, 0);
                setEvaluator(new RGBEvaluator());
                mValueType = int.class;
                break;
            case VALUE_TYPE_CUSTOM:
                // TODO: How to get an 'Object' value?
                valueFrom = a.getFloat(com.android.internal.R.styleable.Animator_valueFrom, 0f);
                valueTo = a.getFloat(com.android.internal.R.styleable.Animator_valueTo, 0f);
                mValueType = Object.class;
                break;
    public Animator() {
    }

        PropertyValuesHolder valuesHolder = new PropertyValuesHolder("", valueFrom, valueTo);
        mValues = new PropertyValuesHolder[1];
        mValues[0] = valuesHolder;
        mValuesMap = new HashMap<String, PropertyValuesHolder>(1);
        mValuesMap.put("", valuesHolder);

        mRepeatCount = a.getInt(com.android.internal.R.styleable.Animator_repeatCount, mRepeatCount);
        mRepeatMode = a.getInt(com.android.internal.R.styleable.Animator_repeatMode, RESTART);

        a.recycle();
    }


    /**
     * Constructs an Animator object with the specified duration and set of
     * values. If the values are a set of PropertyValuesHolder objects, then these objects
@@ -373,6 +294,25 @@ public class Animator<T> extends Animatable {
        mInitialized = true;
    }


    /**
     * Sets the length of the animation.
     *
     * @param duration The length of the animation, in milliseconds.
     */
    public void setDuration(long duration) {
        mDuration = duration;
    }

    /**
     * Gets the length of the animation.
     *
     * @return The length of the animation, in milliseconds.
     */
    public long getDuration() {
        return mDuration;
    }

    /**
     * Sets the position of the animation to the specified point in time. This time should
     * be between 0 and the total duration of the animation, including any repetition. If
@@ -723,11 +663,11 @@ public class Animator<T> extends Animatable {
     * @param playBackwards Whether the Animator should start playing in reverse.
     */
    private void start(boolean playBackwards) {
        mPlayingBackwards = playBackwards;
        if ((mStartDelay == 0) && (Thread.currentThread() == Looper.getMainLooper().getThread())) {
            // This sets the initial value of the animation, prior to actually starting it running
            setCurrentPlayTime(getCurrentPlayTime());
        }
        mPlayingBackwards = playBackwards;
        mPlayingState = STOPPED;
        sPendingAnimations.add(this);
        if (sAnimationHandler == null) {
@@ -738,15 +678,6 @@ public class Animator<T> extends Animatable {
        sAnimationHandler.sendEmptyMessage(ANIMATION_START);
    }

    /**
     * Returns the duration that this animation will run for.
     *
     * @return The length in time of the animation, in milliseconds.
     */
    public long getDuration() {
        return mDuration;
    }

    @Override
    public void start() {
        start(false);
+8 −22
Original line number Diff line number Diff line
@@ -16,9 +16,6 @@

package android.animation;

import android.content.Context;
import android.content.res.TypedArray;
import android.util.AttributeSet;
import android.util.Log;

import java.lang.reflect.Method;
@@ -80,25 +77,6 @@ public final class PropertyAnimator<T> extends Animator<T> {
        return mPropertyName;
    }

    /**
     * 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
     */
    public PropertyAnimator(Context context, AttributeSet attrs) {
        super(context, attrs);

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

        setPropertyName(a.getString(
                com.android.internal.R.styleable.PropertyAnimator_propertyName));


        a.recycle();
    }
    /**
     * Determine the setter or getter function using the JavaBeans convention of setFoo or
     * getFoo for a property named 'foo'. This function figures out what the name of the
@@ -129,6 +107,14 @@ public final class PropertyAnimator<T> extends Animator<T> {
        return returnVal;
    }

    /**
     * Creates a new PropertyAnimator object. This default constructor is primarily for
     * use internally; the other constructors which take parameters are more generally
     * useful.
     */
    public PropertyAnimator() {
    }

    /**
     * A constructor that takes a single property name and set of values. This constructor is
     * used in the simple case of animating a single property.
+3 −3
Original line number Diff line number Diff line
@@ -17,6 +17,7 @@
package android.app;

import android.animation.Animatable;
import android.animation.AnimatableInflater;
import android.animation.PropertyAnimator;
import android.animation.Sequencer;
import android.content.res.TypedArray;
@@ -31,7 +32,6 @@ import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.AnimationUtils;

import java.util.ArrayList;

@@ -257,7 +257,7 @@ final class FragmentManagerImpl implements FragmentManager {
        }
        
        if (fragment.mNextAnim != 0) {
            Animatable anim = AnimationUtils.loadAnimator(mActivity, fragment.mNextAnim);
            Animatable anim = AnimatableInflater.loadAnimatable(mActivity, fragment.mNextAnim);
            if (anim != null) {
                return anim;
            }
@@ -288,7 +288,7 @@ final class FragmentManagerImpl implements FragmentManager {
            return null;
        }
        
        return AnimationUtils.loadAnimator(mActivity, anim);
        return AnimatableInflater.loadAnimatable(mActivity, anim);
    }
    
    void moveToState(Fragment f, int newState, int transit, int transitionStyle) {
Loading