1f4c5bf30b445874cf353e1b96cab94185a39ce6dYigit Boyar/*
2f4c5bf30b445874cf353e1b96cab94185a39ce6dYigit Boyar * Copyright (C) 2014 The Android Open Source Project
3f4c5bf30b445874cf353e1b96cab94185a39ce6dYigit Boyar *
4f4c5bf30b445874cf353e1b96cab94185a39ce6dYigit Boyar * Licensed under the Apache License, Version 2.0 (the "License");
5f4c5bf30b445874cf353e1b96cab94185a39ce6dYigit Boyar * you may not use this file except in compliance with the License.
6f4c5bf30b445874cf353e1b96cab94185a39ce6dYigit Boyar * You may obtain a copy of the License at
7f4c5bf30b445874cf353e1b96cab94185a39ce6dYigit Boyar *
8f4c5bf30b445874cf353e1b96cab94185a39ce6dYigit Boyar *      http://www.apache.org/licenses/LICENSE-2.0
9f4c5bf30b445874cf353e1b96cab94185a39ce6dYigit Boyar *
10f4c5bf30b445874cf353e1b96cab94185a39ce6dYigit Boyar * Unless required by applicable law or agreed to in writing, software
11f4c5bf30b445874cf353e1b96cab94185a39ce6dYigit Boyar * distributed under the License is distributed on an "AS IS" BASIS,
12f4c5bf30b445874cf353e1b96cab94185a39ce6dYigit Boyar * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13f4c5bf30b445874cf353e1b96cab94185a39ce6dYigit Boyar * See the License for the specific language governing permissions and
14f4c5bf30b445874cf353e1b96cab94185a39ce6dYigit Boyar * limitations under the License.
15f4c5bf30b445874cf353e1b96cab94185a39ce6dYigit Boyar */
16f4c5bf30b445874cf353e1b96cab94185a39ce6dYigit Boyar
17f4c5bf30b445874cf353e1b96cab94185a39ce6dYigit Boyarpackage android.animation;
18f4c5bf30b445874cf353e1b96cab94185a39ce6dYigit Boyar
19ac85f90466dd60d2af8ffc3942d503a0de606726Alan Viveretteimport android.content.pm.ActivityInfo.Config;
20d422dc358f0100106dc07d7b903201eb9b043b11Yigit Boyarimport android.content.res.ConstantState;
21f4c5bf30b445874cf353e1b96cab94185a39ce6dYigit Boyarimport android.util.StateSet;
22f4c5bf30b445874cf353e1b96cab94185a39ce6dYigit Boyarimport android.view.View;
23f4c5bf30b445874cf353e1b96cab94185a39ce6dYigit Boyar
24f4c5bf30b445874cf353e1b96cab94185a39ce6dYigit Boyarimport java.lang.ref.WeakReference;
25f4c5bf30b445874cf353e1b96cab94185a39ce6dYigit Boyarimport java.util.ArrayList;
26f4c5bf30b445874cf353e1b96cab94185a39ce6dYigit Boyar
27f4c5bf30b445874cf353e1b96cab94185a39ce6dYigit Boyar/**
28f4c5bf30b445874cf353e1b96cab94185a39ce6dYigit Boyar * Lets you define a number of Animators that will run on the attached View depending on the View's
29f4c5bf30b445874cf353e1b96cab94185a39ce6dYigit Boyar * drawable state.
30f4c5bf30b445874cf353e1b96cab94185a39ce6dYigit Boyar * <p>
31f4c5bf30b445874cf353e1b96cab94185a39ce6dYigit Boyar * It can be defined in an XML file with the <code>&lt;selector></code> element.
32f4c5bf30b445874cf353e1b96cab94185a39ce6dYigit Boyar * Each State Animator is defined in a nested <code>&lt;item></code> element.
33f4c5bf30b445874cf353e1b96cab94185a39ce6dYigit Boyar *
34f4c5bf30b445874cf353e1b96cab94185a39ce6dYigit Boyar * @attr ref android.R.styleable#DrawableStates_state_focused
35f4c5bf30b445874cf353e1b96cab94185a39ce6dYigit Boyar * @attr ref android.R.styleable#DrawableStates_state_window_focused
36f4c5bf30b445874cf353e1b96cab94185a39ce6dYigit Boyar * @attr ref android.R.styleable#DrawableStates_state_enabled
37f4c5bf30b445874cf353e1b96cab94185a39ce6dYigit Boyar * @attr ref android.R.styleable#DrawableStates_state_checkable
38f4c5bf30b445874cf353e1b96cab94185a39ce6dYigit Boyar * @attr ref android.R.styleable#DrawableStates_state_checked
39f4c5bf30b445874cf353e1b96cab94185a39ce6dYigit Boyar * @attr ref android.R.styleable#DrawableStates_state_selected
40f4c5bf30b445874cf353e1b96cab94185a39ce6dYigit Boyar * @attr ref android.R.styleable#DrawableStates_state_activated
41f4c5bf30b445874cf353e1b96cab94185a39ce6dYigit Boyar * @attr ref android.R.styleable#DrawableStates_state_active
42f4c5bf30b445874cf353e1b96cab94185a39ce6dYigit Boyar * @attr ref android.R.styleable#DrawableStates_state_single
43f4c5bf30b445874cf353e1b96cab94185a39ce6dYigit Boyar * @attr ref android.R.styleable#DrawableStates_state_first
44f4c5bf30b445874cf353e1b96cab94185a39ce6dYigit Boyar * @attr ref android.R.styleable#DrawableStates_state_middle
45f4c5bf30b445874cf353e1b96cab94185a39ce6dYigit Boyar * @attr ref android.R.styleable#DrawableStates_state_last
46f4c5bf30b445874cf353e1b96cab94185a39ce6dYigit Boyar * @attr ref android.R.styleable#DrawableStates_state_pressed
47f4c5bf30b445874cf353e1b96cab94185a39ce6dYigit Boyar * @attr ref android.R.styleable#StateListAnimatorItem_animation
48f4c5bf30b445874cf353e1b96cab94185a39ce6dYigit Boyar */
49d422dc358f0100106dc07d7b903201eb9b043b11Yigit Boyarpublic class StateListAnimator implements Cloneable {
50f4c5bf30b445874cf353e1b96cab94185a39ce6dYigit Boyar
51d422dc358f0100106dc07d7b903201eb9b043b11Yigit Boyar    private ArrayList<Tuple> mTuples = new ArrayList<Tuple>();
52f4c5bf30b445874cf353e1b96cab94185a39ce6dYigit Boyar    private Tuple mLastMatch = null;
53f4c5bf30b445874cf353e1b96cab94185a39ce6dYigit Boyar    private Animator mRunningAnimator = null;
54f4c5bf30b445874cf353e1b96cab94185a39ce6dYigit Boyar    private WeakReference<View> mViewRef;
55d422dc358f0100106dc07d7b903201eb9b043b11Yigit Boyar    private StateListAnimatorConstantState mConstantState;
56d422dc358f0100106dc07d7b903201eb9b043b11Yigit Boyar    private AnimatorListenerAdapter mAnimatorListener;
57ac85f90466dd60d2af8ffc3942d503a0de606726Alan Viverette    private @Config int mChangingConfigurations;
58f4c5bf30b445874cf353e1b96cab94185a39ce6dYigit Boyar
59d422dc358f0100106dc07d7b903201eb9b043b11Yigit Boyar    public StateListAnimator() {
60d422dc358f0100106dc07d7b903201eb9b043b11Yigit Boyar        initAnimatorListener();
61d422dc358f0100106dc07d7b903201eb9b043b11Yigit Boyar    }
62d422dc358f0100106dc07d7b903201eb9b043b11Yigit Boyar
63d422dc358f0100106dc07d7b903201eb9b043b11Yigit Boyar    private void initAnimatorListener() {
64d422dc358f0100106dc07d7b903201eb9b043b11Yigit Boyar        mAnimatorListener = new AnimatorListenerAdapter() {
65d422dc358f0100106dc07d7b903201eb9b043b11Yigit Boyar            @Override
66d422dc358f0100106dc07d7b903201eb9b043b11Yigit Boyar            public void onAnimationEnd(Animator animation) {
67d422dc358f0100106dc07d7b903201eb9b043b11Yigit Boyar                animation.setTarget(null);
68d422dc358f0100106dc07d7b903201eb9b043b11Yigit Boyar                if (mRunningAnimator == animation) {
69d422dc358f0100106dc07d7b903201eb9b043b11Yigit Boyar                    mRunningAnimator = null;
70d422dc358f0100106dc07d7b903201eb9b043b11Yigit Boyar                }
71f4c5bf30b445874cf353e1b96cab94185a39ce6dYigit Boyar            }
72d422dc358f0100106dc07d7b903201eb9b043b11Yigit Boyar        };
73d422dc358f0100106dc07d7b903201eb9b043b11Yigit Boyar    }
74f4c5bf30b445874cf353e1b96cab94185a39ce6dYigit Boyar
75f4c5bf30b445874cf353e1b96cab94185a39ce6dYigit Boyar    /**
76f4c5bf30b445874cf353e1b96cab94185a39ce6dYigit Boyar     * Associates the given animator with the provided drawable state specs so that it will be run
77f4c5bf30b445874cf353e1b96cab94185a39ce6dYigit Boyar     * when the View's drawable state matches the specs.
78f4c5bf30b445874cf353e1b96cab94185a39ce6dYigit Boyar     *
79f4c5bf30b445874cf353e1b96cab94185a39ce6dYigit Boyar     * @param specs The drawable state specs to match against
80f4c5bf30b445874cf353e1b96cab94185a39ce6dYigit Boyar     * @param animator The animator to run when the specs match
81f4c5bf30b445874cf353e1b96cab94185a39ce6dYigit Boyar     */
82f4c5bf30b445874cf353e1b96cab94185a39ce6dYigit Boyar    public void addState(int[] specs, Animator animator) {
83f4c5bf30b445874cf353e1b96cab94185a39ce6dYigit Boyar        Tuple tuple = new Tuple(specs, animator);
84f4c5bf30b445874cf353e1b96cab94185a39ce6dYigit Boyar        tuple.mAnimator.addListener(mAnimatorListener);
85f4c5bf30b445874cf353e1b96cab94185a39ce6dYigit Boyar        mTuples.add(tuple);
86d422dc358f0100106dc07d7b903201eb9b043b11Yigit Boyar        mChangingConfigurations |= animator.getChangingConfigurations();
87f4c5bf30b445874cf353e1b96cab94185a39ce6dYigit Boyar    }
88f4c5bf30b445874cf353e1b96cab94185a39ce6dYigit Boyar
89f4c5bf30b445874cf353e1b96cab94185a39ce6dYigit Boyar    /**
90f4c5bf30b445874cf353e1b96cab94185a39ce6dYigit Boyar     * Returns the current {@link android.animation.Animator} which is started because of a state
91f4c5bf30b445874cf353e1b96cab94185a39ce6dYigit Boyar     * change.
92f4c5bf30b445874cf353e1b96cab94185a39ce6dYigit Boyar     *
93f4c5bf30b445874cf353e1b96cab94185a39ce6dYigit Boyar     * @return The currently running Animator or null if no Animator is running
94f4c5bf30b445874cf353e1b96cab94185a39ce6dYigit Boyar     * @hide
95f4c5bf30b445874cf353e1b96cab94185a39ce6dYigit Boyar     */
96f4c5bf30b445874cf353e1b96cab94185a39ce6dYigit Boyar    public Animator getRunningAnimator() {
97f4c5bf30b445874cf353e1b96cab94185a39ce6dYigit Boyar        return mRunningAnimator;
98f4c5bf30b445874cf353e1b96cab94185a39ce6dYigit Boyar    }
99f4c5bf30b445874cf353e1b96cab94185a39ce6dYigit Boyar
100f4c5bf30b445874cf353e1b96cab94185a39ce6dYigit Boyar    /**
101f4c5bf30b445874cf353e1b96cab94185a39ce6dYigit Boyar     * @hide
102f4c5bf30b445874cf353e1b96cab94185a39ce6dYigit Boyar     */
103f4c5bf30b445874cf353e1b96cab94185a39ce6dYigit Boyar    public View getTarget() {
104f4c5bf30b445874cf353e1b96cab94185a39ce6dYigit Boyar        return mViewRef == null ? null : mViewRef.get();
105f4c5bf30b445874cf353e1b96cab94185a39ce6dYigit Boyar    }
106f4c5bf30b445874cf353e1b96cab94185a39ce6dYigit Boyar
107f4c5bf30b445874cf353e1b96cab94185a39ce6dYigit Boyar    /**
108f4c5bf30b445874cf353e1b96cab94185a39ce6dYigit Boyar     * Called by View
109f4c5bf30b445874cf353e1b96cab94185a39ce6dYigit Boyar     * @hide
110f4c5bf30b445874cf353e1b96cab94185a39ce6dYigit Boyar     */
111f4c5bf30b445874cf353e1b96cab94185a39ce6dYigit Boyar    public void setTarget(View view) {
112f4c5bf30b445874cf353e1b96cab94185a39ce6dYigit Boyar        final View current = getTarget();
113f4c5bf30b445874cf353e1b96cab94185a39ce6dYigit Boyar        if (current == view) {
114f4c5bf30b445874cf353e1b96cab94185a39ce6dYigit Boyar            return;
115f4c5bf30b445874cf353e1b96cab94185a39ce6dYigit Boyar        }
116f4c5bf30b445874cf353e1b96cab94185a39ce6dYigit Boyar        if (current != null) {
117f4c5bf30b445874cf353e1b96cab94185a39ce6dYigit Boyar            clearTarget();
118f4c5bf30b445874cf353e1b96cab94185a39ce6dYigit Boyar        }
119f4c5bf30b445874cf353e1b96cab94185a39ce6dYigit Boyar        if (view != null) {
120f4c5bf30b445874cf353e1b96cab94185a39ce6dYigit Boyar            mViewRef = new WeakReference<View>(view);
121f4c5bf30b445874cf353e1b96cab94185a39ce6dYigit Boyar        }
122f4c5bf30b445874cf353e1b96cab94185a39ce6dYigit Boyar
123f4c5bf30b445874cf353e1b96cab94185a39ce6dYigit Boyar    }
124f4c5bf30b445874cf353e1b96cab94185a39ce6dYigit Boyar
125f4c5bf30b445874cf353e1b96cab94185a39ce6dYigit Boyar    private void clearTarget() {
126f4c5bf30b445874cf353e1b96cab94185a39ce6dYigit Boyar        final int size = mTuples.size();
127f4c5bf30b445874cf353e1b96cab94185a39ce6dYigit Boyar        for (int i = 0; i < size; i++) {
128f4c5bf30b445874cf353e1b96cab94185a39ce6dYigit Boyar            mTuples.get(i).mAnimator.setTarget(null);
129f4c5bf30b445874cf353e1b96cab94185a39ce6dYigit Boyar        }
130f4c5bf30b445874cf353e1b96cab94185a39ce6dYigit Boyar        mViewRef = null;
131f4c5bf30b445874cf353e1b96cab94185a39ce6dYigit Boyar        mLastMatch = null;
132f4c5bf30b445874cf353e1b96cab94185a39ce6dYigit Boyar        mRunningAnimator = null;
133f4c5bf30b445874cf353e1b96cab94185a39ce6dYigit Boyar    }
134f4c5bf30b445874cf353e1b96cab94185a39ce6dYigit Boyar
135d422dc358f0100106dc07d7b903201eb9b043b11Yigit Boyar    @Override
136d422dc358f0100106dc07d7b903201eb9b043b11Yigit Boyar    public StateListAnimator clone() {
137d422dc358f0100106dc07d7b903201eb9b043b11Yigit Boyar        try {
138d422dc358f0100106dc07d7b903201eb9b043b11Yigit Boyar            StateListAnimator clone = (StateListAnimator) super.clone();
139d422dc358f0100106dc07d7b903201eb9b043b11Yigit Boyar            clone.mTuples = new ArrayList<Tuple>(mTuples.size());
140d422dc358f0100106dc07d7b903201eb9b043b11Yigit Boyar            clone.mLastMatch = null;
141d422dc358f0100106dc07d7b903201eb9b043b11Yigit Boyar            clone.mRunningAnimator = null;
142d422dc358f0100106dc07d7b903201eb9b043b11Yigit Boyar            clone.mViewRef = null;
143d422dc358f0100106dc07d7b903201eb9b043b11Yigit Boyar            clone.mAnimatorListener = null;
144d422dc358f0100106dc07d7b903201eb9b043b11Yigit Boyar            clone.initAnimatorListener();
145d422dc358f0100106dc07d7b903201eb9b043b11Yigit Boyar            final int tupleSize = mTuples.size();
146d422dc358f0100106dc07d7b903201eb9b043b11Yigit Boyar            for (int i = 0; i < tupleSize; i++) {
147d422dc358f0100106dc07d7b903201eb9b043b11Yigit Boyar                final Tuple tuple = mTuples.get(i);
148d422dc358f0100106dc07d7b903201eb9b043b11Yigit Boyar                final Animator animatorClone = tuple.mAnimator.clone();
149d422dc358f0100106dc07d7b903201eb9b043b11Yigit Boyar                animatorClone.removeListener(mAnimatorListener);
150d422dc358f0100106dc07d7b903201eb9b043b11Yigit Boyar                clone.addState(tuple.mSpecs, animatorClone);
151d422dc358f0100106dc07d7b903201eb9b043b11Yigit Boyar            }
152d422dc358f0100106dc07d7b903201eb9b043b11Yigit Boyar            clone.setChangingConfigurations(getChangingConfigurations());
153d422dc358f0100106dc07d7b903201eb9b043b11Yigit Boyar            return clone;
154d422dc358f0100106dc07d7b903201eb9b043b11Yigit Boyar        } catch (CloneNotSupportedException e) {
155d422dc358f0100106dc07d7b903201eb9b043b11Yigit Boyar            throw new AssertionError("cannot clone state list animator", e);
156d422dc358f0100106dc07d7b903201eb9b043b11Yigit Boyar        }
157d422dc358f0100106dc07d7b903201eb9b043b11Yigit Boyar    }
158d422dc358f0100106dc07d7b903201eb9b043b11Yigit Boyar
159f4c5bf30b445874cf353e1b96cab94185a39ce6dYigit Boyar    /**
160f4c5bf30b445874cf353e1b96cab94185a39ce6dYigit Boyar     * Called by View
161f4c5bf30b445874cf353e1b96cab94185a39ce6dYigit Boyar     * @hide
162f4c5bf30b445874cf353e1b96cab94185a39ce6dYigit Boyar     */
163f4c5bf30b445874cf353e1b96cab94185a39ce6dYigit Boyar    public void setState(int[] state) {
164f4c5bf30b445874cf353e1b96cab94185a39ce6dYigit Boyar        Tuple match = null;
165f4c5bf30b445874cf353e1b96cab94185a39ce6dYigit Boyar        final int count = mTuples.size();
166f4c5bf30b445874cf353e1b96cab94185a39ce6dYigit Boyar        for (int i = 0; i < count; i++) {
167f4c5bf30b445874cf353e1b96cab94185a39ce6dYigit Boyar            final Tuple tuple = mTuples.get(i);
168f4c5bf30b445874cf353e1b96cab94185a39ce6dYigit Boyar            if (StateSet.stateSetMatches(tuple.mSpecs, state)) {
169f4c5bf30b445874cf353e1b96cab94185a39ce6dYigit Boyar                match = tuple;
170f4c5bf30b445874cf353e1b96cab94185a39ce6dYigit Boyar                break;
171f4c5bf30b445874cf353e1b96cab94185a39ce6dYigit Boyar            }
172f4c5bf30b445874cf353e1b96cab94185a39ce6dYigit Boyar        }
173f4c5bf30b445874cf353e1b96cab94185a39ce6dYigit Boyar        if (match == mLastMatch) {
174f4c5bf30b445874cf353e1b96cab94185a39ce6dYigit Boyar            return;
175f4c5bf30b445874cf353e1b96cab94185a39ce6dYigit Boyar        }
176f4c5bf30b445874cf353e1b96cab94185a39ce6dYigit Boyar        if (mLastMatch != null) {
177de5a75ea91cdc9d56f2051aa6ef8e7c1b45febbbYigit Boyar            cancel();
178f4c5bf30b445874cf353e1b96cab94185a39ce6dYigit Boyar        }
179f4c5bf30b445874cf353e1b96cab94185a39ce6dYigit Boyar        mLastMatch = match;
180f4c5bf30b445874cf353e1b96cab94185a39ce6dYigit Boyar        if (match != null) {
181f4c5bf30b445874cf353e1b96cab94185a39ce6dYigit Boyar            start(match);
182f4c5bf30b445874cf353e1b96cab94185a39ce6dYigit Boyar        }
183f4c5bf30b445874cf353e1b96cab94185a39ce6dYigit Boyar    }
184f4c5bf30b445874cf353e1b96cab94185a39ce6dYigit Boyar
185f4c5bf30b445874cf353e1b96cab94185a39ce6dYigit Boyar    private void start(Tuple match) {
186f4c5bf30b445874cf353e1b96cab94185a39ce6dYigit Boyar        match.mAnimator.setTarget(getTarget());
1878619f48fb353740f7fd3f6eaa86fe493377e6cadYigit Boyar        mRunningAnimator = match.mAnimator;
188de5a75ea91cdc9d56f2051aa6ef8e7c1b45febbbYigit Boyar        mRunningAnimator.start();
189f4c5bf30b445874cf353e1b96cab94185a39ce6dYigit Boyar    }
190f4c5bf30b445874cf353e1b96cab94185a39ce6dYigit Boyar
191de5a75ea91cdc9d56f2051aa6ef8e7c1b45febbbYigit Boyar    private void cancel() {
192de5a75ea91cdc9d56f2051aa6ef8e7c1b45febbbYigit Boyar        if (mRunningAnimator != null) {
193de5a75ea91cdc9d56f2051aa6ef8e7c1b45febbbYigit Boyar            mRunningAnimator.cancel();
194de5a75ea91cdc9d56f2051aa6ef8e7c1b45febbbYigit Boyar            mRunningAnimator = null;
195de5a75ea91cdc9d56f2051aa6ef8e7c1b45febbbYigit Boyar        }
196f4c5bf30b445874cf353e1b96cab94185a39ce6dYigit Boyar    }
197f4c5bf30b445874cf353e1b96cab94185a39ce6dYigit Boyar
198f4c5bf30b445874cf353e1b96cab94185a39ce6dYigit Boyar    /**
199f4c5bf30b445874cf353e1b96cab94185a39ce6dYigit Boyar     * @hide
200f4c5bf30b445874cf353e1b96cab94185a39ce6dYigit Boyar     */
201f4c5bf30b445874cf353e1b96cab94185a39ce6dYigit Boyar    public ArrayList<Tuple> getTuples() {
202f4c5bf30b445874cf353e1b96cab94185a39ce6dYigit Boyar        return mTuples;
203f4c5bf30b445874cf353e1b96cab94185a39ce6dYigit Boyar    }
204f4c5bf30b445874cf353e1b96cab94185a39ce6dYigit Boyar
205f4c5bf30b445874cf353e1b96cab94185a39ce6dYigit Boyar    /**
206f4c5bf30b445874cf353e1b96cab94185a39ce6dYigit Boyar     * If there is an animation running for a recent state change, ends it.
207f4c5bf30b445874cf353e1b96cab94185a39ce6dYigit Boyar     * <p>
208f4c5bf30b445874cf353e1b96cab94185a39ce6dYigit Boyar     * This causes the animation to assign the end value(s) to the View.
209f4c5bf30b445874cf353e1b96cab94185a39ce6dYigit Boyar     */
210f4c5bf30b445874cf353e1b96cab94185a39ce6dYigit Boyar    public void jumpToCurrentState() {
211f4c5bf30b445874cf353e1b96cab94185a39ce6dYigit Boyar        if (mRunningAnimator != null) {
212f4c5bf30b445874cf353e1b96cab94185a39ce6dYigit Boyar            mRunningAnimator.end();
213f4c5bf30b445874cf353e1b96cab94185a39ce6dYigit Boyar        }
214f4c5bf30b445874cf353e1b96cab94185a39ce6dYigit Boyar    }
215f4c5bf30b445874cf353e1b96cab94185a39ce6dYigit Boyar
216f4c5bf30b445874cf353e1b96cab94185a39ce6dYigit Boyar    /**
217d422dc358f0100106dc07d7b903201eb9b043b11Yigit Boyar     * Return a mask of the configuration parameters for which this animator may change, requiring
218d422dc358f0100106dc07d7b903201eb9b043b11Yigit Boyar     * that it be re-created.  The default implementation returns whatever was provided through
219d422dc358f0100106dc07d7b903201eb9b043b11Yigit Boyar     * {@link #setChangingConfigurations(int)} or 0 by default.
220d422dc358f0100106dc07d7b903201eb9b043b11Yigit Boyar     *
221d422dc358f0100106dc07d7b903201eb9b043b11Yigit Boyar     * @return Returns a mask of the changing configuration parameters, as defined by
222d422dc358f0100106dc07d7b903201eb9b043b11Yigit Boyar     * {@link android.content.pm.ActivityInfo}.
223d422dc358f0100106dc07d7b903201eb9b043b11Yigit Boyar     *
224d422dc358f0100106dc07d7b903201eb9b043b11Yigit Boyar     * @see android.content.pm.ActivityInfo
225d422dc358f0100106dc07d7b903201eb9b043b11Yigit Boyar     * @hide
226d422dc358f0100106dc07d7b903201eb9b043b11Yigit Boyar     */
227ac85f90466dd60d2af8ffc3942d503a0de606726Alan Viverette    public @Config int getChangingConfigurations() {
228d422dc358f0100106dc07d7b903201eb9b043b11Yigit Boyar        return mChangingConfigurations;
229d422dc358f0100106dc07d7b903201eb9b043b11Yigit Boyar    }
230d422dc358f0100106dc07d7b903201eb9b043b11Yigit Boyar
231d422dc358f0100106dc07d7b903201eb9b043b11Yigit Boyar    /**
232d422dc358f0100106dc07d7b903201eb9b043b11Yigit Boyar     * Set a mask of the configuration parameters for which this animator may change, requiring
233d422dc358f0100106dc07d7b903201eb9b043b11Yigit Boyar     * that it should be recreated from resources instead of being cloned.
234d422dc358f0100106dc07d7b903201eb9b043b11Yigit Boyar     *
235d422dc358f0100106dc07d7b903201eb9b043b11Yigit Boyar     * @param configs A mask of the changing configuration parameters, as
236d422dc358f0100106dc07d7b903201eb9b043b11Yigit Boyar     * defined by {@link android.content.pm.ActivityInfo}.
237d422dc358f0100106dc07d7b903201eb9b043b11Yigit Boyar     *
238d422dc358f0100106dc07d7b903201eb9b043b11Yigit Boyar     * @see android.content.pm.ActivityInfo
239d422dc358f0100106dc07d7b903201eb9b043b11Yigit Boyar     * @hide
240d422dc358f0100106dc07d7b903201eb9b043b11Yigit Boyar     */
241ac85f90466dd60d2af8ffc3942d503a0de606726Alan Viverette    public void setChangingConfigurations(@Config int configs) {
242d422dc358f0100106dc07d7b903201eb9b043b11Yigit Boyar        mChangingConfigurations = configs;
243d422dc358f0100106dc07d7b903201eb9b043b11Yigit Boyar    }
244d422dc358f0100106dc07d7b903201eb9b043b11Yigit Boyar
245d422dc358f0100106dc07d7b903201eb9b043b11Yigit Boyar    /**
246d422dc358f0100106dc07d7b903201eb9b043b11Yigit Boyar     * Sets the changing configurations value to the union of the current changing configurations
247d422dc358f0100106dc07d7b903201eb9b043b11Yigit Boyar     * and the provided configs.
248d422dc358f0100106dc07d7b903201eb9b043b11Yigit Boyar     * This method is called while loading the animator.
249d422dc358f0100106dc07d7b903201eb9b043b11Yigit Boyar     * @hide
250d422dc358f0100106dc07d7b903201eb9b043b11Yigit Boyar     */
251ac85f90466dd60d2af8ffc3942d503a0de606726Alan Viverette    public void appendChangingConfigurations(@Config int configs) {
252d422dc358f0100106dc07d7b903201eb9b043b11Yigit Boyar        mChangingConfigurations |= configs;
253d422dc358f0100106dc07d7b903201eb9b043b11Yigit Boyar    }
254d422dc358f0100106dc07d7b903201eb9b043b11Yigit Boyar
255d422dc358f0100106dc07d7b903201eb9b043b11Yigit Boyar    /**
256d422dc358f0100106dc07d7b903201eb9b043b11Yigit Boyar     * Return a {@link android.content.res.ConstantState} instance that holds the shared state of
257d422dc358f0100106dc07d7b903201eb9b043b11Yigit Boyar     * this Animator.
258d422dc358f0100106dc07d7b903201eb9b043b11Yigit Boyar     * <p>
259d422dc358f0100106dc07d7b903201eb9b043b11Yigit Boyar     * This constant state is used to create new instances of this animator when needed. Default
260d422dc358f0100106dc07d7b903201eb9b043b11Yigit Boyar     * implementation creates a new {@link StateListAnimatorConstantState}. You can override this
261d422dc358f0100106dc07d7b903201eb9b043b11Yigit Boyar     * method to provide your custom logic or return null if you don't want this animator to be
262d422dc358f0100106dc07d7b903201eb9b043b11Yigit Boyar     * cached.
263d422dc358f0100106dc07d7b903201eb9b043b11Yigit Boyar     *
264d422dc358f0100106dc07d7b903201eb9b043b11Yigit Boyar     * @return The {@link android.content.res.ConstantState} associated to this Animator.
265d422dc358f0100106dc07d7b903201eb9b043b11Yigit Boyar     * @see android.content.res.ConstantState
266d422dc358f0100106dc07d7b903201eb9b043b11Yigit Boyar     * @see #clone()
267d422dc358f0100106dc07d7b903201eb9b043b11Yigit Boyar     * @hide
268d422dc358f0100106dc07d7b903201eb9b043b11Yigit Boyar     */
269d422dc358f0100106dc07d7b903201eb9b043b11Yigit Boyar    public ConstantState<StateListAnimator> createConstantState() {
270d422dc358f0100106dc07d7b903201eb9b043b11Yigit Boyar        return new StateListAnimatorConstantState(this);
271d422dc358f0100106dc07d7b903201eb9b043b11Yigit Boyar    }
272d422dc358f0100106dc07d7b903201eb9b043b11Yigit Boyar
273d422dc358f0100106dc07d7b903201eb9b043b11Yigit Boyar    /**
274f4c5bf30b445874cf353e1b96cab94185a39ce6dYigit Boyar     * @hide
275f4c5bf30b445874cf353e1b96cab94185a39ce6dYigit Boyar     */
276f4c5bf30b445874cf353e1b96cab94185a39ce6dYigit Boyar    public static class Tuple {
277f4c5bf30b445874cf353e1b96cab94185a39ce6dYigit Boyar
278f4c5bf30b445874cf353e1b96cab94185a39ce6dYigit Boyar        final int[] mSpecs;
279f4c5bf30b445874cf353e1b96cab94185a39ce6dYigit Boyar
280f4c5bf30b445874cf353e1b96cab94185a39ce6dYigit Boyar        final Animator mAnimator;
281f4c5bf30b445874cf353e1b96cab94185a39ce6dYigit Boyar
282f4c5bf30b445874cf353e1b96cab94185a39ce6dYigit Boyar        private Tuple(int[] specs, Animator animator) {
283f4c5bf30b445874cf353e1b96cab94185a39ce6dYigit Boyar            mSpecs = specs;
284f4c5bf30b445874cf353e1b96cab94185a39ce6dYigit Boyar            mAnimator = animator;
285f4c5bf30b445874cf353e1b96cab94185a39ce6dYigit Boyar        }
286f4c5bf30b445874cf353e1b96cab94185a39ce6dYigit Boyar
287f4c5bf30b445874cf353e1b96cab94185a39ce6dYigit Boyar        /**
288f4c5bf30b445874cf353e1b96cab94185a39ce6dYigit Boyar         * @hide
289f4c5bf30b445874cf353e1b96cab94185a39ce6dYigit Boyar         */
290f4c5bf30b445874cf353e1b96cab94185a39ce6dYigit Boyar        public int[] getSpecs() {
291f4c5bf30b445874cf353e1b96cab94185a39ce6dYigit Boyar            return mSpecs;
292f4c5bf30b445874cf353e1b96cab94185a39ce6dYigit Boyar        }
293f4c5bf30b445874cf353e1b96cab94185a39ce6dYigit Boyar
294f4c5bf30b445874cf353e1b96cab94185a39ce6dYigit Boyar        /**
295f4c5bf30b445874cf353e1b96cab94185a39ce6dYigit Boyar         * @hide
296f4c5bf30b445874cf353e1b96cab94185a39ce6dYigit Boyar         */
297f4c5bf30b445874cf353e1b96cab94185a39ce6dYigit Boyar        public Animator getAnimator() {
298f4c5bf30b445874cf353e1b96cab94185a39ce6dYigit Boyar            return mAnimator;
299f4c5bf30b445874cf353e1b96cab94185a39ce6dYigit Boyar        }
300f4c5bf30b445874cf353e1b96cab94185a39ce6dYigit Boyar    }
301d422dc358f0100106dc07d7b903201eb9b043b11Yigit Boyar
302d422dc358f0100106dc07d7b903201eb9b043b11Yigit Boyar    /**
303d422dc358f0100106dc07d7b903201eb9b043b11Yigit Boyar     * Creates a constant state which holds changing configurations information associated with the
304d422dc358f0100106dc07d7b903201eb9b043b11Yigit Boyar     * given Animator.
305d422dc358f0100106dc07d7b903201eb9b043b11Yigit Boyar     * <p>
306d422dc358f0100106dc07d7b903201eb9b043b11Yigit Boyar     * When new instance is called, default implementation clones the Animator.
307d422dc358f0100106dc07d7b903201eb9b043b11Yigit Boyar     */
308d422dc358f0100106dc07d7b903201eb9b043b11Yigit Boyar    private static class StateListAnimatorConstantState
309d422dc358f0100106dc07d7b903201eb9b043b11Yigit Boyar            extends ConstantState<StateListAnimator> {
310d422dc358f0100106dc07d7b903201eb9b043b11Yigit Boyar
311d422dc358f0100106dc07d7b903201eb9b043b11Yigit Boyar        final StateListAnimator mAnimator;
312d422dc358f0100106dc07d7b903201eb9b043b11Yigit Boyar
313ac85f90466dd60d2af8ffc3942d503a0de606726Alan Viverette        @Config int mChangingConf;
314d422dc358f0100106dc07d7b903201eb9b043b11Yigit Boyar
315d422dc358f0100106dc07d7b903201eb9b043b11Yigit Boyar        public StateListAnimatorConstantState(StateListAnimator animator) {
316d422dc358f0100106dc07d7b903201eb9b043b11Yigit Boyar            mAnimator = animator;
317d422dc358f0100106dc07d7b903201eb9b043b11Yigit Boyar            mAnimator.mConstantState = this;
318d422dc358f0100106dc07d7b903201eb9b043b11Yigit Boyar            mChangingConf = mAnimator.getChangingConfigurations();
319d422dc358f0100106dc07d7b903201eb9b043b11Yigit Boyar        }
320d422dc358f0100106dc07d7b903201eb9b043b11Yigit Boyar
321d422dc358f0100106dc07d7b903201eb9b043b11Yigit Boyar        @Override
322ac85f90466dd60d2af8ffc3942d503a0de606726Alan Viverette        public @Config int getChangingConfigurations() {
323d422dc358f0100106dc07d7b903201eb9b043b11Yigit Boyar            return mChangingConf;
324d422dc358f0100106dc07d7b903201eb9b043b11Yigit Boyar        }
325d422dc358f0100106dc07d7b903201eb9b043b11Yigit Boyar
326d422dc358f0100106dc07d7b903201eb9b043b11Yigit Boyar        @Override
327d422dc358f0100106dc07d7b903201eb9b043b11Yigit Boyar        public StateListAnimator newInstance() {
328d422dc358f0100106dc07d7b903201eb9b043b11Yigit Boyar            final StateListAnimator clone = mAnimator.clone();
329d422dc358f0100106dc07d7b903201eb9b043b11Yigit Boyar            clone.mConstantState = this;
330d422dc358f0100106dc07d7b903201eb9b043b11Yigit Boyar            return clone;
331d422dc358f0100106dc07d7b903201eb9b043b11Yigit Boyar        }
332d422dc358f0100106dc07d7b903201eb9b043b11Yigit Boyar    }
333f4c5bf30b445874cf353e1b96cab94185a39ce6dYigit Boyar}
334