19840efe3dbdc7026521da8576574c55120782f6cChris Banes/* 29840efe3dbdc7026521da8576574c55120782f6cChris Banes * Copyright (C) 2015 The Android Open Source Project 39840efe3dbdc7026521da8576574c55120782f6cChris Banes * 49840efe3dbdc7026521da8576574c55120782f6cChris Banes * Licensed under the Apache License, Version 2.0 (the "License"); 59840efe3dbdc7026521da8576574c55120782f6cChris Banes * you may not use this file except in compliance with the License. 69840efe3dbdc7026521da8576574c55120782f6cChris Banes * You may obtain a copy of the License at 79840efe3dbdc7026521da8576574c55120782f6cChris Banes * 89840efe3dbdc7026521da8576574c55120782f6cChris Banes * http://www.apache.org/licenses/LICENSE-2.0 99840efe3dbdc7026521da8576574c55120782f6cChris Banes * 109840efe3dbdc7026521da8576574c55120782f6cChris Banes * Unless required by applicable law or agreed to in writing, software 119840efe3dbdc7026521da8576574c55120782f6cChris Banes * distributed under the License is distributed on an "AS IS" BASIS, 129840efe3dbdc7026521da8576574c55120782f6cChris Banes * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 139840efe3dbdc7026521da8576574c55120782f6cChris Banes * See the License for the specific language governing permissions and 149840efe3dbdc7026521da8576574c55120782f6cChris Banes * limitations under the License. 159840efe3dbdc7026521da8576574c55120782f6cChris Banes */ 169840efe3dbdc7026521da8576574c55120782f6cChris Banes 179840efe3dbdc7026521da8576574c55120782f6cChris Banespackage android.support.design.widget; 189840efe3dbdc7026521da8576574c55120782f6cChris Banes 199840efe3dbdc7026521da8576574c55120782f6cChris Banesimport android.util.StateSet; 209840efe3dbdc7026521da8576574c55120782f6cChris Banes 219840efe3dbdc7026521da8576574c55120782f6cChris Banesimport java.util.ArrayList; 229840efe3dbdc7026521da8576574c55120782f6cChris Banes 239840efe3dbdc7026521da8576574c55120782f6cChris Banesfinal class StateListAnimator { 249840efe3dbdc7026521da8576574c55120782f6cChris Banes 259840efe3dbdc7026521da8576574c55120782f6cChris Banes private final ArrayList<Tuple> mTuples = new ArrayList<>(); 269840efe3dbdc7026521da8576574c55120782f6cChris Banes 279840efe3dbdc7026521da8576574c55120782f6cChris Banes private Tuple mLastMatch = null; 28657ea1100fee4750f148f9d0dcb7e7e2028f105eAurimas Liutikas ValueAnimatorCompat mRunningAnimator = null; 299840efe3dbdc7026521da8576574c55120782f6cChris Banes 305a0083cc8328f05b15efe0293b7aa83723cdd9adChris Banes private final ValueAnimatorCompat.AnimatorListener mAnimationListener 315a0083cc8328f05b15efe0293b7aa83723cdd9adChris Banes = new ValueAnimatorCompat.AnimatorListenerAdapter() { 329840efe3dbdc7026521da8576574c55120782f6cChris Banes @Override 335a0083cc8328f05b15efe0293b7aa83723cdd9adChris Banes public void onAnimationEnd(ValueAnimatorCompat animator) { 345a0083cc8328f05b15efe0293b7aa83723cdd9adChris Banes if (mRunningAnimator == animator) { 355a0083cc8328f05b15efe0293b7aa83723cdd9adChris Banes mRunningAnimator = null; 369840efe3dbdc7026521da8576574c55120782f6cChris Banes } 379840efe3dbdc7026521da8576574c55120782f6cChris Banes } 389840efe3dbdc7026521da8576574c55120782f6cChris Banes }; 399840efe3dbdc7026521da8576574c55120782f6cChris Banes 409840efe3dbdc7026521da8576574c55120782f6cChris Banes /** 419840efe3dbdc7026521da8576574c55120782f6cChris Banes * Associates the given Animation with the provided drawable state specs so that it will be run 429840efe3dbdc7026521da8576574c55120782f6cChris Banes * when the View's drawable state matches the specs. 439840efe3dbdc7026521da8576574c55120782f6cChris Banes * 449840efe3dbdc7026521da8576574c55120782f6cChris Banes * @param specs The drawable state specs to match against 455a0083cc8328f05b15efe0293b7aa83723cdd9adChris Banes * @param animator The animator to run when the specs match 469840efe3dbdc7026521da8576574c55120782f6cChris Banes */ 475a0083cc8328f05b15efe0293b7aa83723cdd9adChris Banes public void addState(int[] specs, ValueAnimatorCompat animator) { 485a0083cc8328f05b15efe0293b7aa83723cdd9adChris Banes Tuple tuple = new Tuple(specs, animator); 495a0083cc8328f05b15efe0293b7aa83723cdd9adChris Banes animator.addListener(mAnimationListener); 509840efe3dbdc7026521da8576574c55120782f6cChris Banes mTuples.add(tuple); 519840efe3dbdc7026521da8576574c55120782f6cChris Banes } 529840efe3dbdc7026521da8576574c55120782f6cChris Banes 539840efe3dbdc7026521da8576574c55120782f6cChris Banes /** 549840efe3dbdc7026521da8576574c55120782f6cChris Banes * Called by View 559840efe3dbdc7026521da8576574c55120782f6cChris Banes */ 569840efe3dbdc7026521da8576574c55120782f6cChris Banes void setState(int[] state) { 579840efe3dbdc7026521da8576574c55120782f6cChris Banes Tuple match = null; 589840efe3dbdc7026521da8576574c55120782f6cChris Banes final int count = mTuples.size(); 599840efe3dbdc7026521da8576574c55120782f6cChris Banes for (int i = 0; i < count; i++) { 609840efe3dbdc7026521da8576574c55120782f6cChris Banes final Tuple tuple = mTuples.get(i); 619840efe3dbdc7026521da8576574c55120782f6cChris Banes if (StateSet.stateSetMatches(tuple.mSpecs, state)) { 629840efe3dbdc7026521da8576574c55120782f6cChris Banes match = tuple; 639840efe3dbdc7026521da8576574c55120782f6cChris Banes break; 649840efe3dbdc7026521da8576574c55120782f6cChris Banes } 659840efe3dbdc7026521da8576574c55120782f6cChris Banes } 669840efe3dbdc7026521da8576574c55120782f6cChris Banes if (match == mLastMatch) { 679840efe3dbdc7026521da8576574c55120782f6cChris Banes return; 689840efe3dbdc7026521da8576574c55120782f6cChris Banes } 699840efe3dbdc7026521da8576574c55120782f6cChris Banes if (mLastMatch != null) { 709840efe3dbdc7026521da8576574c55120782f6cChris Banes cancel(); 719840efe3dbdc7026521da8576574c55120782f6cChris Banes } 7292d279ce7d51389b254846fbc802f6950b33eeffChris Banes 739840efe3dbdc7026521da8576574c55120782f6cChris Banes mLastMatch = match; 7492d279ce7d51389b254846fbc802f6950b33eeffChris Banes 755a0083cc8328f05b15efe0293b7aa83723cdd9adChris Banes if (match != null) { 769840efe3dbdc7026521da8576574c55120782f6cChris Banes start(match); 779840efe3dbdc7026521da8576574c55120782f6cChris Banes } 789840efe3dbdc7026521da8576574c55120782f6cChris Banes } 799840efe3dbdc7026521da8576574c55120782f6cChris Banes 809840efe3dbdc7026521da8576574c55120782f6cChris Banes private void start(Tuple match) { 815a0083cc8328f05b15efe0293b7aa83723cdd9adChris Banes mRunningAnimator = match.mAnimator; 825a0083cc8328f05b15efe0293b7aa83723cdd9adChris Banes mRunningAnimator.start(); 839840efe3dbdc7026521da8576574c55120782f6cChris Banes } 849840efe3dbdc7026521da8576574c55120782f6cChris Banes 859840efe3dbdc7026521da8576574c55120782f6cChris Banes private void cancel() { 865a0083cc8328f05b15efe0293b7aa83723cdd9adChris Banes if (mRunningAnimator != null) { 875a0083cc8328f05b15efe0293b7aa83723cdd9adChris Banes mRunningAnimator.cancel(); 885a0083cc8328f05b15efe0293b7aa83723cdd9adChris Banes mRunningAnimator = null; 899840efe3dbdc7026521da8576574c55120782f6cChris Banes } 909840efe3dbdc7026521da8576574c55120782f6cChris Banes } 919840efe3dbdc7026521da8576574c55120782f6cChris Banes 929840efe3dbdc7026521da8576574c55120782f6cChris Banes /** 935a0083cc8328f05b15efe0293b7aa83723cdd9adChris Banes * If there is an animation running for a recent state change, ends it. 945a0083cc8328f05b15efe0293b7aa83723cdd9adChris Banes * 955a0083cc8328f05b15efe0293b7aa83723cdd9adChris Banes * <p>This causes the animation to assign the end value(s) to the View.</p> 969840efe3dbdc7026521da8576574c55120782f6cChris Banes */ 979840efe3dbdc7026521da8576574c55120782f6cChris Banes public void jumpToCurrentState() { 985a0083cc8328f05b15efe0293b7aa83723cdd9adChris Banes if (mRunningAnimator != null) { 995a0083cc8328f05b15efe0293b7aa83723cdd9adChris Banes mRunningAnimator.end(); 1005a0083cc8328f05b15efe0293b7aa83723cdd9adChris Banes mRunningAnimator = null; 1019840efe3dbdc7026521da8576574c55120782f6cChris Banes } 1029840efe3dbdc7026521da8576574c55120782f6cChris Banes } 1039840efe3dbdc7026521da8576574c55120782f6cChris Banes 1049840efe3dbdc7026521da8576574c55120782f6cChris Banes static class Tuple { 1059840efe3dbdc7026521da8576574c55120782f6cChris Banes final int[] mSpecs; 1065a0083cc8328f05b15efe0293b7aa83723cdd9adChris Banes final ValueAnimatorCompat mAnimator; 1079840efe3dbdc7026521da8576574c55120782f6cChris Banes 108657ea1100fee4750f148f9d0dcb7e7e2028f105eAurimas Liutikas Tuple(int[] specs, ValueAnimatorCompat animator) { 1099840efe3dbdc7026521da8576574c55120782f6cChris Banes mSpecs = specs; 1105a0083cc8328f05b15efe0293b7aa83723cdd9adChris Banes mAnimator = animator; 1119840efe3dbdc7026521da8576574c55120782f6cChris Banes } 1129840efe3dbdc7026521da8576574c55120782f6cChris Banes } 1139840efe3dbdc7026521da8576574c55120782f6cChris Banes}