1a8301e2eb5a083a73f58331279c86e8ec7b11a48Mark Wei/*
2a8301e2eb5a083a73f58331279c86e8ec7b11a48Mark Wei * Copyright (C) 2013 The Android Open Source Project
3a8301e2eb5a083a73f58331279c86e8ec7b11a48Mark Wei *
4a8301e2eb5a083a73f58331279c86e8ec7b11a48Mark Wei * Licensed under the Apache License, Version 2.0 (the "License");
5a8301e2eb5a083a73f58331279c86e8ec7b11a48Mark Wei * you may not use this file except in compliance with the License.
6a8301e2eb5a083a73f58331279c86e8ec7b11a48Mark Wei * You may obtain a copy of the License at
7a8301e2eb5a083a73f58331279c86e8ec7b11a48Mark Wei *
8a8301e2eb5a083a73f58331279c86e8ec7b11a48Mark Wei *      http://www.apache.org/licenses/LICENSE-2.0
9a8301e2eb5a083a73f58331279c86e8ec7b11a48Mark Wei *
10a8301e2eb5a083a73f58331279c86e8ec7b11a48Mark Wei * Unless required by applicable law or agreed to in writing, software
11a8301e2eb5a083a73f58331279c86e8ec7b11a48Mark Wei * distributed under the License is distributed on an "AS IS" BASIS,
12a8301e2eb5a083a73f58331279c86e8ec7b11a48Mark Wei * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13a8301e2eb5a083a73f58331279c86e8ec7b11a48Mark Wei * See the License for the specific language governing permissions and
14a8301e2eb5a083a73f58331279c86e8ec7b11a48Mark Wei * limitations under the License.
15a8301e2eb5a083a73f58331279c86e8ec7b11a48Mark Wei */
16a8301e2eb5a083a73f58331279c86e8ec7b11a48Mark Weipackage com.android.mail.bitmap;
17a8301e2eb5a083a73f58331279c86e8ec7b11a48Mark Wei
18a8301e2eb5a083a73f58331279c86e8ec7b11a48Mark Weiimport android.animation.ValueAnimator;
19a8301e2eb5a083a73f58331279c86e8ec7b11a48Mark Weiimport android.animation.ValueAnimator.AnimatorUpdateListener;
20a8301e2eb5a083a73f58331279c86e8ec7b11a48Mark Weiimport android.content.res.Resources;
21a8301e2eb5a083a73f58331279c86e8ec7b11a48Mark Weiimport android.graphics.Bitmap;
22a8301e2eb5a083a73f58331279c86e8ec7b11a48Mark Weiimport android.graphics.BitmapFactory;
23a8301e2eb5a083a73f58331279c86e8ec7b11a48Mark Weiimport android.graphics.Canvas;
24a8301e2eb5a083a73f58331279c86e8ec7b11a48Mark Weiimport android.graphics.ColorFilter;
25a8301e2eb5a083a73f58331279c86e8ec7b11a48Mark Weiimport android.graphics.Matrix;
26a8301e2eb5a083a73f58331279c86e8ec7b11a48Mark Weiimport android.graphics.Paint;
27a8301e2eb5a083a73f58331279c86e8ec7b11a48Mark Weiimport android.graphics.PixelFormat;
28a8301e2eb5a083a73f58331279c86e8ec7b11a48Mark Weiimport android.graphics.Rect;
29a8301e2eb5a083a73f58331279c86e8ec7b11a48Mark Weiimport android.graphics.drawable.Drawable;
30a8301e2eb5a083a73f58331279c86e8ec7b11a48Mark Wei
312b806edc62eb8e83c77edc471fda4652281a15c4James Lemieuximport com.android.mail.R;
32a8301e2eb5a083a73f58331279c86e8ec7b11a48Mark Wei
33a8301e2eb5a083a73f58331279c86e8ec7b11a48Mark Wei/**
345f79af7b356c3a8ecd8cd77fcbde673de9023b50James Lemieux * Custom FlipDrawable which has a {@link ContactDrawable} on the front,
35a8301e2eb5a083a73f58331279c86e8ec7b11a48Mark Wei * and a {@link CheckmarkDrawable} on the back.
36a8301e2eb5a083a73f58331279c86e8ec7b11a48Mark Wei */
375f79af7b356c3a8ecd8cd77fcbde673de9023b50James Lemieuxpublic class CheckableContactFlipDrawable extends FlipDrawable implements AnimatorUpdateListener {
38a8301e2eb5a083a73f58331279c86e8ec7b11a48Mark Wei
395f79af7b356c3a8ecd8cd77fcbde673de9023b50James Lemieux    private final ContactDrawable mContactDrawable;
40a8301e2eb5a083a73f58331279c86e8ec7b11a48Mark Wei    private final CheckmarkDrawable mCheckmarkDrawable;
41a8301e2eb5a083a73f58331279c86e8ec7b11a48Mark Wei
42a8301e2eb5a083a73f58331279c86e8ec7b11a48Mark Wei    private final ValueAnimator mCheckmarkScaleAnimator;
43a8301e2eb5a083a73f58331279c86e8ec7b11a48Mark Wei    private final ValueAnimator mCheckmarkAlphaAnimator;
44a8301e2eb5a083a73f58331279c86e8ec7b11a48Mark Wei
45a8301e2eb5a083a73f58331279c86e8ec7b11a48Mark Wei    private static final int POST_FLIP_DURATION_MS = 150;
46a8301e2eb5a083a73f58331279c86e8ec7b11a48Mark Wei
47a8301e2eb5a083a73f58331279c86e8ec7b11a48Mark Wei    private static final float CHECKMARK_SCALE_BEGIN_VALUE = 0.2f;
48a8301e2eb5a083a73f58331279c86e8ec7b11a48Mark Wei    private static final float CHECKMARK_ALPHA_BEGIN_VALUE = 0f;
49a8301e2eb5a083a73f58331279c86e8ec7b11a48Mark Wei
50a8301e2eb5a083a73f58331279c86e8ec7b11a48Mark Wei    /** Must be <= 1f since the animation value is used as a percentage. */
51a8301e2eb5a083a73f58331279c86e8ec7b11a48Mark Wei    private static final float END_VALUE = 1f;
52a8301e2eb5a083a73f58331279c86e8ec7b11a48Mark Wei
535f79af7b356c3a8ecd8cd77fcbde673de9023b50James Lemieux    public CheckableContactFlipDrawable(final Resources res, final int flipDurationMs) {
545f79af7b356c3a8ecd8cd77fcbde673de9023b50James Lemieux        super(new ContactDrawable(res), new CheckmarkDrawable(res), flipDurationMs,
55a8301e2eb5a083a73f58331279c86e8ec7b11a48Mark Wei                0 /* preFlipDurationMs */, POST_FLIP_DURATION_MS);
56a8301e2eb5a083a73f58331279c86e8ec7b11a48Mark Wei
575f79af7b356c3a8ecd8cd77fcbde673de9023b50James Lemieux        mContactDrawable = (ContactDrawable) mFront;
58a8301e2eb5a083a73f58331279c86e8ec7b11a48Mark Wei        mCheckmarkDrawable = (CheckmarkDrawable) mBack;
59a8301e2eb5a083a73f58331279c86e8ec7b11a48Mark Wei
60a8301e2eb5a083a73f58331279c86e8ec7b11a48Mark Wei        // We will create checkmark animations that are synchronized with the flipping animation.
61a8301e2eb5a083a73f58331279c86e8ec7b11a48Mark Wei        // The entire delay + duration of the checkmark animation needs to equal the entire
62a8301e2eb5a083a73f58331279c86e8ec7b11a48Mark Wei        // duration of the flip animation (where delay is 0).
63a8301e2eb5a083a73f58331279c86e8ec7b11a48Mark Wei
64a8301e2eb5a083a73f58331279c86e8ec7b11a48Mark Wei        // The checkmark animation is in effect only when the back drawable is being shown.
65a8301e2eb5a083a73f58331279c86e8ec7b11a48Mark Wei        // For the flip animation duration    <pre>[_][]|[][_]<post>
66a8301e2eb5a083a73f58331279c86e8ec7b11a48Mark Wei        // The checkmark animation will be    |--delay--|-duration-|
67a8301e2eb5a083a73f58331279c86e8ec7b11a48Mark Wei
68a8301e2eb5a083a73f58331279c86e8ec7b11a48Mark Wei        // Need delay to skip the first half of the flip duration.
69a8301e2eb5a083a73f58331279c86e8ec7b11a48Mark Wei        final long animationDelay = mPreFlipDurationMs + mFlipDurationMs / 2;
70a8301e2eb5a083a73f58331279c86e8ec7b11a48Mark Wei        // Actual duration is the second half of the flip duration.
71a8301e2eb5a083a73f58331279c86e8ec7b11a48Mark Wei        final long animationDuration = mFlipDurationMs / 2 + mPostFlipDurationMs;
72a8301e2eb5a083a73f58331279c86e8ec7b11a48Mark Wei
73a8301e2eb5a083a73f58331279c86e8ec7b11a48Mark Wei        mCheckmarkScaleAnimator = ValueAnimator.ofFloat(CHECKMARK_SCALE_BEGIN_VALUE, END_VALUE)
74a8301e2eb5a083a73f58331279c86e8ec7b11a48Mark Wei                .setDuration(animationDuration);
75a8301e2eb5a083a73f58331279c86e8ec7b11a48Mark Wei        mCheckmarkScaleAnimator.setStartDelay(animationDelay);
76a8301e2eb5a083a73f58331279c86e8ec7b11a48Mark Wei        mCheckmarkScaleAnimator.addUpdateListener(this);
77a8301e2eb5a083a73f58331279c86e8ec7b11a48Mark Wei
78a8301e2eb5a083a73f58331279c86e8ec7b11a48Mark Wei        mCheckmarkAlphaAnimator = ValueAnimator.ofFloat(CHECKMARK_ALPHA_BEGIN_VALUE, END_VALUE)
79a8301e2eb5a083a73f58331279c86e8ec7b11a48Mark Wei                .setDuration(animationDuration);
80a8301e2eb5a083a73f58331279c86e8ec7b11a48Mark Wei        mCheckmarkAlphaAnimator.setStartDelay(animationDelay);
81a8301e2eb5a083a73f58331279c86e8ec7b11a48Mark Wei        mCheckmarkAlphaAnimator.addUpdateListener(this);
82a8301e2eb5a083a73f58331279c86e8ec7b11a48Mark Wei    }
83a8301e2eb5a083a73f58331279c86e8ec7b11a48Mark Wei
84a8301e2eb5a083a73f58331279c86e8ec7b11a48Mark Wei    @Override
85a8301e2eb5a083a73f58331279c86e8ec7b11a48Mark Wei    public void reset(final boolean side) {
86a8301e2eb5a083a73f58331279c86e8ec7b11a48Mark Wei        super.reset(side);
87a8301e2eb5a083a73f58331279c86e8ec7b11a48Mark Wei        if (mCheckmarkScaleAnimator == null) {
88a8301e2eb5a083a73f58331279c86e8ec7b11a48Mark Wei            // Call from super's constructor. Not yet initialized.
89a8301e2eb5a083a73f58331279c86e8ec7b11a48Mark Wei            return;
90a8301e2eb5a083a73f58331279c86e8ec7b11a48Mark Wei        }
91a8301e2eb5a083a73f58331279c86e8ec7b11a48Mark Wei        mCheckmarkScaleAnimator.cancel();
92a8301e2eb5a083a73f58331279c86e8ec7b11a48Mark Wei        mCheckmarkAlphaAnimator.cancel();
93a8301e2eb5a083a73f58331279c86e8ec7b11a48Mark Wei        mCheckmarkDrawable.setScaleAnimatorValue(side ? CHECKMARK_SCALE_BEGIN_VALUE : END_VALUE);
94a8301e2eb5a083a73f58331279c86e8ec7b11a48Mark Wei        mCheckmarkDrawable.setAlphaAnimatorValue(side ? CHECKMARK_ALPHA_BEGIN_VALUE : END_VALUE);
95a8301e2eb5a083a73f58331279c86e8ec7b11a48Mark Wei    }
96a8301e2eb5a083a73f58331279c86e8ec7b11a48Mark Wei
97a8301e2eb5a083a73f58331279c86e8ec7b11a48Mark Wei    @Override
98a8301e2eb5a083a73f58331279c86e8ec7b11a48Mark Wei    public void flip() {
99a8301e2eb5a083a73f58331279c86e8ec7b11a48Mark Wei        super.flip();
100a8301e2eb5a083a73f58331279c86e8ec7b11a48Mark Wei        // Keep the checkmark animators in sync with the flip animator.
101a8301e2eb5a083a73f58331279c86e8ec7b11a48Mark Wei        if (mCheckmarkScaleAnimator.isStarted()) {
102a8301e2eb5a083a73f58331279c86e8ec7b11a48Mark Wei            mCheckmarkScaleAnimator.reverse();
103a8301e2eb5a083a73f58331279c86e8ec7b11a48Mark Wei            mCheckmarkAlphaAnimator.reverse();
104a8301e2eb5a083a73f58331279c86e8ec7b11a48Mark Wei        } else {
105a8301e2eb5a083a73f58331279c86e8ec7b11a48Mark Wei            if (!getSideFlippingTowards() /* front to back */) {
106a8301e2eb5a083a73f58331279c86e8ec7b11a48Mark Wei                mCheckmarkScaleAnimator.start();
107a8301e2eb5a083a73f58331279c86e8ec7b11a48Mark Wei                mCheckmarkAlphaAnimator.start();
108a8301e2eb5a083a73f58331279c86e8ec7b11a48Mark Wei            } else /* back to front */ {
109a8301e2eb5a083a73f58331279c86e8ec7b11a48Mark Wei                mCheckmarkScaleAnimator.reverse();
110a8301e2eb5a083a73f58331279c86e8ec7b11a48Mark Wei                mCheckmarkAlphaAnimator.reverse();
111a8301e2eb5a083a73f58331279c86e8ec7b11a48Mark Wei            }
112a8301e2eb5a083a73f58331279c86e8ec7b11a48Mark Wei        }
113a8301e2eb5a083a73f58331279c86e8ec7b11a48Mark Wei    }
114a8301e2eb5a083a73f58331279c86e8ec7b11a48Mark Wei
1155f79af7b356c3a8ecd8cd77fcbde673de9023b50James Lemieux    public ContactDrawable getContactDrawable() {
1165f79af7b356c3a8ecd8cd77fcbde673de9023b50James Lemieux        return mContactDrawable;
117a8301e2eb5a083a73f58331279c86e8ec7b11a48Mark Wei    }
118a8301e2eb5a083a73f58331279c86e8ec7b11a48Mark Wei
119a8301e2eb5a083a73f58331279c86e8ec7b11a48Mark Wei    @Override
120a8301e2eb5a083a73f58331279c86e8ec7b11a48Mark Wei    public void onAnimationUpdate(final ValueAnimator animation) {
121a8301e2eb5a083a73f58331279c86e8ec7b11a48Mark Wei        //noinspection ConstantConditions
122a8301e2eb5a083a73f58331279c86e8ec7b11a48Mark Wei        final float value = (Float) animation.getAnimatedValue();
123a8301e2eb5a083a73f58331279c86e8ec7b11a48Mark Wei
124a8301e2eb5a083a73f58331279c86e8ec7b11a48Mark Wei        if (animation == mCheckmarkScaleAnimator) {
125a8301e2eb5a083a73f58331279c86e8ec7b11a48Mark Wei            mCheckmarkDrawable.setScaleAnimatorValue(value);
126a8301e2eb5a083a73f58331279c86e8ec7b11a48Mark Wei        } else if (animation == mCheckmarkAlphaAnimator) {
127a8301e2eb5a083a73f58331279c86e8ec7b11a48Mark Wei            mCheckmarkDrawable.setAlphaAnimatorValue(value);
128a8301e2eb5a083a73f58331279c86e8ec7b11a48Mark Wei        }
129a8301e2eb5a083a73f58331279c86e8ec7b11a48Mark Wei    }
130a8301e2eb5a083a73f58331279c86e8ec7b11a48Mark Wei
131a8301e2eb5a083a73f58331279c86e8ec7b11a48Mark Wei    /**
132a8301e2eb5a083a73f58331279c86e8ec7b11a48Mark Wei     * Meant to be used as the with a FlipDrawable. The animator driving this Drawable should be
133a8301e2eb5a083a73f58331279c86e8ec7b11a48Mark Wei     * more or less in sync with the containing FlipDrawable's flip animator.
134a8301e2eb5a083a73f58331279c86e8ec7b11a48Mark Wei     */
135a8301e2eb5a083a73f58331279c86e8ec7b11a48Mark Wei    private static class CheckmarkDrawable extends Drawable {
136a8301e2eb5a083a73f58331279c86e8ec7b11a48Mark Wei
137a8301e2eb5a083a73f58331279c86e8ec7b11a48Mark Wei        private static Bitmap CHECKMARK;
138a8301e2eb5a083a73f58331279c86e8ec7b11a48Mark Wei        private static int sBackgroundColor;
139a8301e2eb5a083a73f58331279c86e8ec7b11a48Mark Wei
140a8301e2eb5a083a73f58331279c86e8ec7b11a48Mark Wei        private final Paint mPaint;
141a8301e2eb5a083a73f58331279c86e8ec7b11a48Mark Wei
142a8301e2eb5a083a73f58331279c86e8ec7b11a48Mark Wei        private float mScaleFraction;
143a8301e2eb5a083a73f58331279c86e8ec7b11a48Mark Wei        private float mAlphaFraction;
144a8301e2eb5a083a73f58331279c86e8ec7b11a48Mark Wei
145a8301e2eb5a083a73f58331279c86e8ec7b11a48Mark Wei        private static final Matrix sMatrix = new Matrix();
146a8301e2eb5a083a73f58331279c86e8ec7b11a48Mark Wei
147a8301e2eb5a083a73f58331279c86e8ec7b11a48Mark Wei        public CheckmarkDrawable(final Resources res) {
148a8301e2eb5a083a73f58331279c86e8ec7b11a48Mark Wei            if (CHECKMARK == null) {
1490617562219869efe1fc3fd92170f1f8535397f51James Lemieux                CHECKMARK = BitmapFactory.decodeResource(res, R.drawable.ic_check_wht_24dp);
1502b806edc62eb8e83c77edc471fda4652281a15c4James Lemieux                sBackgroundColor = res.getColor(R.color.checkmark_tile_background_color);
151a8301e2eb5a083a73f58331279c86e8ec7b11a48Mark Wei            }
152a8301e2eb5a083a73f58331279c86e8ec7b11a48Mark Wei            mPaint = new Paint();
153a8301e2eb5a083a73f58331279c86e8ec7b11a48Mark Wei            mPaint.setAntiAlias(true);
154a8301e2eb5a083a73f58331279c86e8ec7b11a48Mark Wei            mPaint.setFilterBitmap(true);
155a8301e2eb5a083a73f58331279c86e8ec7b11a48Mark Wei            mPaint.setColor(sBackgroundColor);
156a8301e2eb5a083a73f58331279c86e8ec7b11a48Mark Wei        }
157a8301e2eb5a083a73f58331279c86e8ec7b11a48Mark Wei
158a8301e2eb5a083a73f58331279c86e8ec7b11a48Mark Wei        @Override
159a8301e2eb5a083a73f58331279c86e8ec7b11a48Mark Wei        public void draw(final Canvas canvas) {
160a8301e2eb5a083a73f58331279c86e8ec7b11a48Mark Wei            final Rect bounds = getBounds();
161a8301e2eb5a083a73f58331279c86e8ec7b11a48Mark Wei            if (!isVisible() || bounds.isEmpty()) {
162a8301e2eb5a083a73f58331279c86e8ec7b11a48Mark Wei                return;
163a8301e2eb5a083a73f58331279c86e8ec7b11a48Mark Wei            }
164a8301e2eb5a083a73f58331279c86e8ec7b11a48Mark Wei
1655f79af7b356c3a8ecd8cd77fcbde673de9023b50James Lemieux            canvas.drawCircle(bounds.centerX(), bounds.centerY(), bounds.width() / 2, mPaint);
166a8301e2eb5a083a73f58331279c86e8ec7b11a48Mark Wei
167a8301e2eb5a083a73f58331279c86e8ec7b11a48Mark Wei            // Scale the checkmark.
168a8301e2eb5a083a73f58331279c86e8ec7b11a48Mark Wei            sMatrix.reset();
169a8301e2eb5a083a73f58331279c86e8ec7b11a48Mark Wei            sMatrix.setScale(mScaleFraction, mScaleFraction, CHECKMARK.getWidth() / 2,
170a8301e2eb5a083a73f58331279c86e8ec7b11a48Mark Wei                    CHECKMARK.getHeight() / 2);
171a8301e2eb5a083a73f58331279c86e8ec7b11a48Mark Wei            sMatrix.postTranslate(bounds.centerX() - CHECKMARK.getWidth() / 2,
172a8301e2eb5a083a73f58331279c86e8ec7b11a48Mark Wei                    bounds.centerY() - CHECKMARK.getHeight() / 2);
173a8301e2eb5a083a73f58331279c86e8ec7b11a48Mark Wei
174a8301e2eb5a083a73f58331279c86e8ec7b11a48Mark Wei            // Fade the checkmark.
175a8301e2eb5a083a73f58331279c86e8ec7b11a48Mark Wei            final int oldAlpha = mPaint.getAlpha();
176a8301e2eb5a083a73f58331279c86e8ec7b11a48Mark Wei            // Interpolate the alpha.
177a8301e2eb5a083a73f58331279c86e8ec7b11a48Mark Wei            mPaint.setAlpha((int) (oldAlpha * mAlphaFraction));
178a8301e2eb5a083a73f58331279c86e8ec7b11a48Mark Wei            canvas.drawBitmap(CHECKMARK, sMatrix, mPaint);
179a8301e2eb5a083a73f58331279c86e8ec7b11a48Mark Wei            // Restore the alpha.
180a8301e2eb5a083a73f58331279c86e8ec7b11a48Mark Wei            mPaint.setAlpha(oldAlpha);
181a8301e2eb5a083a73f58331279c86e8ec7b11a48Mark Wei        }
182a8301e2eb5a083a73f58331279c86e8ec7b11a48Mark Wei
183a8301e2eb5a083a73f58331279c86e8ec7b11a48Mark Wei        @Override
184a8301e2eb5a083a73f58331279c86e8ec7b11a48Mark Wei        public void setAlpha(final int alpha) {
185a8301e2eb5a083a73f58331279c86e8ec7b11a48Mark Wei            mPaint.setAlpha(alpha);
186a8301e2eb5a083a73f58331279c86e8ec7b11a48Mark Wei        }
187a8301e2eb5a083a73f58331279c86e8ec7b11a48Mark Wei
188a8301e2eb5a083a73f58331279c86e8ec7b11a48Mark Wei        @Override
189a8301e2eb5a083a73f58331279c86e8ec7b11a48Mark Wei        public void setColorFilter(final ColorFilter cf) {
190a8301e2eb5a083a73f58331279c86e8ec7b11a48Mark Wei            mPaint.setColorFilter(cf);
191a8301e2eb5a083a73f58331279c86e8ec7b11a48Mark Wei        }
192a8301e2eb5a083a73f58331279c86e8ec7b11a48Mark Wei
193a8301e2eb5a083a73f58331279c86e8ec7b11a48Mark Wei        @Override
194a8301e2eb5a083a73f58331279c86e8ec7b11a48Mark Wei        public int getOpacity() {
195a8301e2eb5a083a73f58331279c86e8ec7b11a48Mark Wei            // Always a gray background.
196a8301e2eb5a083a73f58331279c86e8ec7b11a48Mark Wei            return PixelFormat.OPAQUE;
197a8301e2eb5a083a73f58331279c86e8ec7b11a48Mark Wei        }
198a8301e2eb5a083a73f58331279c86e8ec7b11a48Mark Wei
199a8301e2eb5a083a73f58331279c86e8ec7b11a48Mark Wei        /**
200a8301e2eb5a083a73f58331279c86e8ec7b11a48Mark Wei         * Set value as a fraction from 0f to 1f.
201a8301e2eb5a083a73f58331279c86e8ec7b11a48Mark Wei         */
202a8301e2eb5a083a73f58331279c86e8ec7b11a48Mark Wei        public void setScaleAnimatorValue(final float value) {
203a8301e2eb5a083a73f58331279c86e8ec7b11a48Mark Wei            final float old = mScaleFraction;
204a8301e2eb5a083a73f58331279c86e8ec7b11a48Mark Wei            mScaleFraction = value;
205a8301e2eb5a083a73f58331279c86e8ec7b11a48Mark Wei            if (old != mScaleFraction) {
206a8301e2eb5a083a73f58331279c86e8ec7b11a48Mark Wei                invalidateSelf();
207a8301e2eb5a083a73f58331279c86e8ec7b11a48Mark Wei            }
208a8301e2eb5a083a73f58331279c86e8ec7b11a48Mark Wei        }
209a8301e2eb5a083a73f58331279c86e8ec7b11a48Mark Wei
210a8301e2eb5a083a73f58331279c86e8ec7b11a48Mark Wei        /**
211a8301e2eb5a083a73f58331279c86e8ec7b11a48Mark Wei         * Set value as a fraction from 0f to 1f.
212a8301e2eb5a083a73f58331279c86e8ec7b11a48Mark Wei         */
213a8301e2eb5a083a73f58331279c86e8ec7b11a48Mark Wei        public void setAlphaAnimatorValue(final float value) {
214a8301e2eb5a083a73f58331279c86e8ec7b11a48Mark Wei            final float old = mAlphaFraction;
215a8301e2eb5a083a73f58331279c86e8ec7b11a48Mark Wei            mAlphaFraction = value;
216a8301e2eb5a083a73f58331279c86e8ec7b11a48Mark Wei            if (old != mAlphaFraction) {
217a8301e2eb5a083a73f58331279c86e8ec7b11a48Mark Wei                invalidateSelf();
218a8301e2eb5a083a73f58331279c86e8ec7b11a48Mark Wei            }
219a8301e2eb5a083a73f58331279c86e8ec7b11a48Mark Wei        }
220a8301e2eb5a083a73f58331279c86e8ec7b11a48Mark Wei    }
221a8301e2eb5a083a73f58331279c86e8ec7b11a48Mark Wei}
222