InterruptibleInOutAnimator.java revision 472b281d5cb4f5660df981a6c912266b9f5703fe
1150fbab7de7df45ce0e2d08fb0f0be87ff091c2fWinson Chung/*
2150fbab7de7df45ce0e2d08fb0f0be87ff091c2fWinson Chung * Copyright (C) 2010 The Android Open Source Project
3150fbab7de7df45ce0e2d08fb0f0be87ff091c2fWinson Chung *
4150fbab7de7df45ce0e2d08fb0f0be87ff091c2fWinson Chung * Licensed under the Apache License, Version 2.0 (the "License");
5150fbab7de7df45ce0e2d08fb0f0be87ff091c2fWinson Chung * you may not use this file except in compliance with the License.
6150fbab7de7df45ce0e2d08fb0f0be87ff091c2fWinson Chung * You may obtain a copy of the License at
7150fbab7de7df45ce0e2d08fb0f0be87ff091c2fWinson Chung *
8150fbab7de7df45ce0e2d08fb0f0be87ff091c2fWinson Chung *      http://www.apache.org/licenses/LICENSE-2.0
9150fbab7de7df45ce0e2d08fb0f0be87ff091c2fWinson Chung *
10150fbab7de7df45ce0e2d08fb0f0be87ff091c2fWinson Chung * Unless required by applicable law or agreed to in writing, software
11150fbab7de7df45ce0e2d08fb0f0be87ff091c2fWinson Chung * distributed under the License is distributed on an "AS IS" BASIS,
12150fbab7de7df45ce0e2d08fb0f0be87ff091c2fWinson Chung * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13150fbab7de7df45ce0e2d08fb0f0be87ff091c2fWinson Chung * See the License for the specific language governing permissions and
14150fbab7de7df45ce0e2d08fb0f0be87ff091c2fWinson Chung * limitations under the License.
15150fbab7de7df45ce0e2d08fb0f0be87ff091c2fWinson Chung */
16150fbab7de7df45ce0e2d08fb0f0be87ff091c2fWinson Chung
17150fbab7de7df45ce0e2d08fb0f0be87ff091c2fWinson Chungpackage com.android.launcher2;
18150fbab7de7df45ce0e2d08fb0f0be87ff091c2fWinson Chung
194be866d3a1665aa2098cb5d38d535b1ad1aab6d6Joe Onoratoimport android.animation.Animator;
204be866d3a1665aa2098cb5d38d535b1ad1aab6d6Joe Onoratoimport android.animation.AnimatorListenerAdapter;
21472b281d5cb4f5660df981a6c912266b9f5703feChet Haaseimport android.animation.ObjectAnimator;
22150fbab7de7df45ce0e2d08fb0f0be87ff091c2fWinson Chungimport android.animation.ValueAnimator;
23150fbab7de7df45ce0e2d08fb0f0be87ff091c2fWinson Chungimport android.util.Log;
24150fbab7de7df45ce0e2d08fb0f0be87ff091c2fWinson Chung
25150fbab7de7df45ce0e2d08fb0f0be87ff091c2fWinson Chung/**
26150fbab7de7df45ce0e2d08fb0f0be87ff091c2fWinson Chung * A convenience class for two-way animations, e.g. a fadeIn/fadeOut animation.
27150fbab7de7df45ce0e2d08fb0f0be87ff091c2fWinson Chung * With a regular ValueAnimator, if you call reverse to show the 'out' animation, you'll get
28150fbab7de7df45ce0e2d08fb0f0be87ff091c2fWinson Chung * a frame-by-frame mirror of the 'in' animation -- i.e., the interpolated values will
29150fbab7de7df45ce0e2d08fb0f0be87ff091c2fWinson Chung * be exactly reversed. Using this class, both the 'in' and the 'out' animation use the
30150fbab7de7df45ce0e2d08fb0f0be87ff091c2fWinson Chung * interpolator in the same direction.
31150fbab7de7df45ce0e2d08fb0f0be87ff091c2fWinson Chung */
32472b281d5cb4f5660df981a6c912266b9f5703feChet Haasepublic class InterruptibleInOutAnimator {
33150fbab7de7df45ce0e2d08fb0f0be87ff091c2fWinson Chung    private long mOriginalDuration;
34472b281d5cb4f5660df981a6c912266b9f5703feChet Haase    private float mOriginalFromValue;
35472b281d5cb4f5660df981a6c912266b9f5703feChet Haase    private float mOriginalToValue;
36472b281d5cb4f5660df981a6c912266b9f5703feChet Haase    private ValueAnimator mAnimator;
37150fbab7de7df45ce0e2d08fb0f0be87ff091c2fWinson Chung
384be866d3a1665aa2098cb5d38d535b1ad1aab6d6Joe Onorato    private boolean mFirstRun = true;
394be866d3a1665aa2098cb5d38d535b1ad1aab6d6Joe Onorato
404be866d3a1665aa2098cb5d38d535b1ad1aab6d6Joe Onorato    private Object mTag = null;
414be866d3a1665aa2098cb5d38d535b1ad1aab6d6Joe Onorato
42fe6bd87881e47b9ff38f58bd083042ae0f6a39d7Patrick Dubroy    private static final int STOPPED = 0;
43fe6bd87881e47b9ff38f58bd083042ae0f6a39d7Patrick Dubroy    private static final int IN = 1;
44fe6bd87881e47b9ff38f58bd083042ae0f6a39d7Patrick Dubroy    private static final int OUT = 2;
45fe6bd87881e47b9ff38f58bd083042ae0f6a39d7Patrick Dubroy
46472b281d5cb4f5660df981a6c912266b9f5703feChet Haase
47fe6bd87881e47b9ff38f58bd083042ae0f6a39d7Patrick Dubroy    private int mDirection = STOPPED;
48fe6bd87881e47b9ff38f58bd083042ae0f6a39d7Patrick Dubroy
49472b281d5cb4f5660df981a6c912266b9f5703feChet Haase    public InterruptibleInOutAnimator(long duration, float fromValue, float toValue) {
50472b281d5cb4f5660df981a6c912266b9f5703feChet Haase        mAnimator = ValueAnimator.ofFloat(fromValue, toValue).setDuration(duration);
51150fbab7de7df45ce0e2d08fb0f0be87ff091c2fWinson Chung        mOriginalDuration = duration;
52150fbab7de7df45ce0e2d08fb0f0be87ff091c2fWinson Chung        mOriginalFromValue = fromValue;
53150fbab7de7df45ce0e2d08fb0f0be87ff091c2fWinson Chung        mOriginalToValue = toValue;
54150fbab7de7df45ce0e2d08fb0f0be87ff091c2fWinson Chung    }
55150fbab7de7df45ce0e2d08fb0f0be87ff091c2fWinson Chung
56fe6bd87881e47b9ff38f58bd083042ae0f6a39d7Patrick Dubroy    private void animate(int direction) {
57472b281d5cb4f5660df981a6c912266b9f5703feChet Haase        final long currentPlayTime = mAnimator.getCurrentPlayTime();
58472b281d5cb4f5660df981a6c912266b9f5703feChet Haase        final float toValue = (direction == IN) ? mOriginalToValue : mOriginalFromValue;
59472b281d5cb4f5660df981a6c912266b9f5703feChet Haase        final float startValue = mFirstRun ? mOriginalFromValue :
60472b281d5cb4f5660df981a6c912266b9f5703feChet Haase                ((Float) mAnimator.getAnimatedValue()).floatValue();
61fe6bd87881e47b9ff38f58bd083042ae0f6a39d7Patrick Dubroy
62fe6bd87881e47b9ff38f58bd083042ae0f6a39d7Patrick Dubroy        // Make sure it's stopped before we modify any values
63150fbab7de7df45ce0e2d08fb0f0be87ff091c2fWinson Chung        cancel();
64fe6bd87881e47b9ff38f58bd083042ae0f6a39d7Patrick Dubroy
654be866d3a1665aa2098cb5d38d535b1ad1aab6d6Joe Onorato        if (startValue != toValue) {
66fe6bd87881e47b9ff38f58bd083042ae0f6a39d7Patrick Dubroy            mDirection = direction;
67472b281d5cb4f5660df981a6c912266b9f5703feChet Haase            mAnimator.setDuration(mOriginalDuration - currentPlayTime);
68472b281d5cb4f5660df981a6c912266b9f5703feChet Haase            mAnimator.setFloatValues(startValue, toValue);
69472b281d5cb4f5660df981a6c912266b9f5703feChet Haase            mAnimator.start();
704be866d3a1665aa2098cb5d38d535b1ad1aab6d6Joe Onorato            mFirstRun = false;
714be866d3a1665aa2098cb5d38d535b1ad1aab6d6Joe Onorato        }
72150fbab7de7df45ce0e2d08fb0f0be87ff091c2fWinson Chung    }
73150fbab7de7df45ce0e2d08fb0f0be87ff091c2fWinson Chung
74fe6bd87881e47b9ff38f58bd083042ae0f6a39d7Patrick Dubroy    public void cancel() {
75472b281d5cb4f5660df981a6c912266b9f5703feChet Haase        mAnimator.cancel();
76fe6bd87881e47b9ff38f58bd083042ae0f6a39d7Patrick Dubroy        mDirection = STOPPED;
77fe6bd87881e47b9ff38f58bd083042ae0f6a39d7Patrick Dubroy    }
78fe6bd87881e47b9ff38f58bd083042ae0f6a39d7Patrick Dubroy
79fe6bd87881e47b9ff38f58bd083042ae0f6a39d7Patrick Dubroy    public void end() {
80472b281d5cb4f5660df981a6c912266b9f5703feChet Haase        mAnimator.end();
81fe6bd87881e47b9ff38f58bd083042ae0f6a39d7Patrick Dubroy        mDirection = STOPPED;
82fe6bd87881e47b9ff38f58bd083042ae0f6a39d7Patrick Dubroy    }
83fe6bd87881e47b9ff38f58bd083042ae0f6a39d7Patrick Dubroy
84fe6bd87881e47b9ff38f58bd083042ae0f6a39d7Patrick Dubroy    /**
85fe6bd87881e47b9ff38f58bd083042ae0f6a39d7Patrick Dubroy     * Return true when the animation is not running and it hasn't even been started.
86fe6bd87881e47b9ff38f58bd083042ae0f6a39d7Patrick Dubroy     */
87fe6bd87881e47b9ff38f58bd083042ae0f6a39d7Patrick Dubroy    public boolean isStopped() {
88fe6bd87881e47b9ff38f58bd083042ae0f6a39d7Patrick Dubroy        return mDirection == STOPPED;
89fe6bd87881e47b9ff38f58bd083042ae0f6a39d7Patrick Dubroy    }
90fe6bd87881e47b9ff38f58bd083042ae0f6a39d7Patrick Dubroy
91150fbab7de7df45ce0e2d08fb0f0be87ff091c2fWinson Chung    /**
92150fbab7de7df45ce0e2d08fb0f0be87ff091c2fWinson Chung     * This is the equivalent of calling Animator.start(), except that it can be called when
93150fbab7de7df45ce0e2d08fb0f0be87ff091c2fWinson Chung     * the animation is running in the opposite direction, in which case we reverse
94150fbab7de7df45ce0e2d08fb0f0be87ff091c2fWinson Chung     * direction and animate for a correspondingly shorter duration.
95150fbab7de7df45ce0e2d08fb0f0be87ff091c2fWinson Chung     */
96150fbab7de7df45ce0e2d08fb0f0be87ff091c2fWinson Chung    public void animateIn() {
97fe6bd87881e47b9ff38f58bd083042ae0f6a39d7Patrick Dubroy        animate(IN);
98150fbab7de7df45ce0e2d08fb0f0be87ff091c2fWinson Chung    }
99150fbab7de7df45ce0e2d08fb0f0be87ff091c2fWinson Chung
100150fbab7de7df45ce0e2d08fb0f0be87ff091c2fWinson Chung    /**
101150fbab7de7df45ce0e2d08fb0f0be87ff091c2fWinson Chung     * This is the roughly the equivalent of calling Animator.reverse(), except that it uses the
102150fbab7de7df45ce0e2d08fb0f0be87ff091c2fWinson Chung     * same interpolation curve as animateIn(), rather than mirroring it. Also, like animateIn(),
103150fbab7de7df45ce0e2d08fb0f0be87ff091c2fWinson Chung     * if the animation is currently running in the opposite direction, we reverse
104150fbab7de7df45ce0e2d08fb0f0be87ff091c2fWinson Chung     * direction and animate for a correspondingly shorter duration.
105150fbab7de7df45ce0e2d08fb0f0be87ff091c2fWinson Chung     */
106150fbab7de7df45ce0e2d08fb0f0be87ff091c2fWinson Chung    public void animateOut() {
107fe6bd87881e47b9ff38f58bd083042ae0f6a39d7Patrick Dubroy        animate(OUT);
1084be866d3a1665aa2098cb5d38d535b1ad1aab6d6Joe Onorato    }
1094be866d3a1665aa2098cb5d38d535b1ad1aab6d6Joe Onorato
1104be866d3a1665aa2098cb5d38d535b1ad1aab6d6Joe Onorato    public void setTag(Object tag) {
1114be866d3a1665aa2098cb5d38d535b1ad1aab6d6Joe Onorato        mTag = tag;
1124be866d3a1665aa2098cb5d38d535b1ad1aab6d6Joe Onorato    }
1134be866d3a1665aa2098cb5d38d535b1ad1aab6d6Joe Onorato
1144be866d3a1665aa2098cb5d38d535b1ad1aab6d6Joe Onorato    public Object getTag() {
1154be866d3a1665aa2098cb5d38d535b1ad1aab6d6Joe Onorato        return mTag;
116150fbab7de7df45ce0e2d08fb0f0be87ff091c2fWinson Chung    }
117472b281d5cb4f5660df981a6c912266b9f5703feChet Haase
118472b281d5cb4f5660df981a6c912266b9f5703feChet Haase    public ValueAnimator getAnimator() {
119472b281d5cb4f5660df981a6c912266b9f5703feChet Haase        return mAnimator;
120472b281d5cb4f5660df981a6c912266b9f5703feChet Haase    }
121150fbab7de7df45ce0e2d08fb0f0be87ff091c2fWinson Chung}
122