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

Commit 71fcc470 authored by Chet Haase's avatar Chet Haase Committed by Android (Google) Code Review
Browse files

Merge "Change animator xml importing to use new inflater class"

parents 089a3854 d51d368f
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