UndoBarView.java revision 517e1bd25305d4e82d101a8c06be0119dde2eab3
16b891c6a3739f8c49d42f9db6fc76cb92c7c5f25Chih-Chung Chang/*
26b891c6a3739f8c49d42f9db6fc76cb92c7c5f25Chih-Chung Chang * Copyright (C) 2012 The Android Open Source Project
36b891c6a3739f8c49d42f9db6fc76cb92c7c5f25Chih-Chung Chang *
46b891c6a3739f8c49d42f9db6fc76cb92c7c5f25Chih-Chung Chang * Licensed under the Apache License, Version 2.0 (the "License");
56b891c6a3739f8c49d42f9db6fc76cb92c7c5f25Chih-Chung Chang * you may not use this file except in compliance with the License.
66b891c6a3739f8c49d42f9db6fc76cb92c7c5f25Chih-Chung Chang * You may obtain a copy of the License at
76b891c6a3739f8c49d42f9db6fc76cb92c7c5f25Chih-Chung Chang *
86b891c6a3739f8c49d42f9db6fc76cb92c7c5f25Chih-Chung Chang *      http://www.apache.org/licenses/LICENSE-2.0
96b891c6a3739f8c49d42f9db6fc76cb92c7c5f25Chih-Chung Chang *
106b891c6a3739f8c49d42f9db6fc76cb92c7c5f25Chih-Chung Chang * Unless required by applicable law or agreed to in writing, software
116b891c6a3739f8c49d42f9db6fc76cb92c7c5f25Chih-Chung Chang * distributed under the License is distributed on an "AS IS" BASIS,
126b891c6a3739f8c49d42f9db6fc76cb92c7c5f25Chih-Chung Chang * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
136b891c6a3739f8c49d42f9db6fc76cb92c7c5f25Chih-Chung Chang * See the License for the specific language governing permissions and
146b891c6a3739f8c49d42f9db6fc76cb92c7c5f25Chih-Chung Chang * limitations under the License.
156b891c6a3739f8c49d42f9db6fc76cb92c7c5f25Chih-Chung Chang */
166b891c6a3739f8c49d42f9db6fc76cb92c7c5f25Chih-Chung Chang
176b891c6a3739f8c49d42f9db6fc76cb92c7c5f25Chih-Chung Changpackage com.android.gallery3d.ui;
186b891c6a3739f8c49d42f9db6fc76cb92c7c5f25Chih-Chung Chang
196b891c6a3739f8c49d42f9db6fc76cb92c7c5f25Chih-Chung Changimport android.content.Context;
206b891c6a3739f8c49d42f9db6fc76cb92c7c5f25Chih-Chung Changimport android.view.MotionEvent;
216b891c6a3739f8c49d42f9db6fc76cb92c7c5f25Chih-Chung Chang
226b891c6a3739f8c49d42f9db6fc76cb92c7c5f25Chih-Chung Changimport com.android.gallery3d.R;
23517e1bd25305d4e82d101a8c06be0119dde2eab3Chih-Chung Changimport com.android.gallery3d.common.Utils;
246b891c6a3739f8c49d42f9db6fc76cb92c7c5f25Chih-Chung Changimport com.android.gallery3d.util.GalleryUtils;
256b891c6a3739f8c49d42f9db6fc76cb92c7c5f25Chih-Chung Chang
266b891c6a3739f8c49d42f9db6fc76cb92c7c5f25Chih-Chung Changpublic class UndoBarView extends GLView {
276b891c6a3739f8c49d42f9db6fc76cb92c7c5f25Chih-Chung Chang    private static final String TAG = "UndoBarView";
286b891c6a3739f8c49d42f9db6fc76cb92c7c5f25Chih-Chung Chang
296b891c6a3739f8c49d42f9db6fc76cb92c7c5f25Chih-Chung Chang    private static final int WHITE = 0xFFFFFFFF;
306b891c6a3739f8c49d42f9db6fc76cb92c7c5f25Chih-Chung Chang    private static final int GRAY = 0xFFAAAAAA;
316b891c6a3739f8c49d42f9db6fc76cb92c7c5f25Chih-Chung Chang
326b891c6a3739f8c49d42f9db6fc76cb92c7c5f25Chih-Chung Chang    private final NinePatchTexture mPanel;
336b891c6a3739f8c49d42f9db6fc76cb92c7c5f25Chih-Chung Chang    private final StringTexture mUndoText;
346b891c6a3739f8c49d42f9db6fc76cb92c7c5f25Chih-Chung Chang    private final StringTexture mDeletedText;
356b891c6a3739f8c49d42f9db6fc76cb92c7c5f25Chih-Chung Chang    private final ResourceTexture mUndoIcon;
366b891c6a3739f8c49d42f9db6fc76cb92c7c5f25Chih-Chung Chang    private final int mBarHeight;
376b891c6a3739f8c49d42f9db6fc76cb92c7c5f25Chih-Chung Chang    private final int mBarMargin;
386b891c6a3739f8c49d42f9db6fc76cb92c7c5f25Chih-Chung Chang    private final int mUndoTextMargin;
396b891c6a3739f8c49d42f9db6fc76cb92c7c5f25Chih-Chung Chang    private final int mIconSize;
406b891c6a3739f8c49d42f9db6fc76cb92c7c5f25Chih-Chung Chang    private final int mIconMargin;
416b891c6a3739f8c49d42f9db6fc76cb92c7c5f25Chih-Chung Chang    private final int mSeparatorTopMargin;
426b891c6a3739f8c49d42f9db6fc76cb92c7c5f25Chih-Chung Chang    private final int mSeparatorBottomMargin;
436b891c6a3739f8c49d42f9db6fc76cb92c7c5f25Chih-Chung Chang    private final int mSeparatorRightMargin;
446b891c6a3739f8c49d42f9db6fc76cb92c7c5f25Chih-Chung Chang    private final int mSeparatorWidth;
456b891c6a3739f8c49d42f9db6fc76cb92c7c5f25Chih-Chung Chang    private final int mDeletedTextMargin;
466b891c6a3739f8c49d42f9db6fc76cb92c7c5f25Chih-Chung Chang    private final int mClickRegion;
476b891c6a3739f8c49d42f9db6fc76cb92c7c5f25Chih-Chung Chang
486b891c6a3739f8c49d42f9db6fc76cb92c7c5f25Chih-Chung Chang    private OnClickListener mOnClickListener;
496b891c6a3739f8c49d42f9db6fc76cb92c7c5f25Chih-Chung Chang    private boolean mDownOnButton;
506b891c6a3739f8c49d42f9db6fc76cb92c7c5f25Chih-Chung Chang
516b891c6a3739f8c49d42f9db6fc76cb92c7c5f25Chih-Chung Chang    // This is the layout of UndoBarView. The unit is dp.
526b891c6a3739f8c49d42f9db6fc76cb92c7c5f25Chih-Chung Chang    //
536b891c6a3739f8c49d42f9db6fc76cb92c7c5f25Chih-Chung Chang    //    +-+----+----------------+-+--+----+-+------+--+-+
546b891c6a3739f8c49d42f9db6fc76cb92c7c5f25Chih-Chung Chang    // 48 | |    | Deleted        | |  | <- | | UNDO |  | |
556b891c6a3739f8c49d42f9db6fc76cb92c7c5f25Chih-Chung Chang    //    +-+----+----------------+-+--+----+-+------+--+-+
566b891c6a3739f8c49d42f9db6fc76cb92c7c5f25Chih-Chung Chang    //     4  16                   1 12  32  8        16 4
576b891c6a3739f8c49d42f9db6fc76cb92c7c5f25Chih-Chung Chang    public UndoBarView(Context context) {
586b891c6a3739f8c49d42f9db6fc76cb92c7c5f25Chih-Chung Chang        mBarHeight = (int) GalleryUtils.dpToPixel(48);
596b891c6a3739f8c49d42f9db6fc76cb92c7c5f25Chih-Chung Chang        mBarMargin = (int) GalleryUtils.dpToPixel(4);
606b891c6a3739f8c49d42f9db6fc76cb92c7c5f25Chih-Chung Chang        mUndoTextMargin = (int) GalleryUtils.dpToPixel(16);
616b891c6a3739f8c49d42f9db6fc76cb92c7c5f25Chih-Chung Chang        mIconMargin = (int) GalleryUtils.dpToPixel(8);
626b891c6a3739f8c49d42f9db6fc76cb92c7c5f25Chih-Chung Chang        mIconSize = (int) GalleryUtils.dpToPixel(32);
636b891c6a3739f8c49d42f9db6fc76cb92c7c5f25Chih-Chung Chang        mSeparatorRightMargin = (int) GalleryUtils.dpToPixel(12);
646b891c6a3739f8c49d42f9db6fc76cb92c7c5f25Chih-Chung Chang        mSeparatorTopMargin = (int) GalleryUtils.dpToPixel(10);
656b891c6a3739f8c49d42f9db6fc76cb92c7c5f25Chih-Chung Chang        mSeparatorBottomMargin = (int) GalleryUtils.dpToPixel(10);
666b891c6a3739f8c49d42f9db6fc76cb92c7c5f25Chih-Chung Chang        mSeparatorWidth = (int) GalleryUtils.dpToPixel(1);
676b891c6a3739f8c49d42f9db6fc76cb92c7c5f25Chih-Chung Chang        mDeletedTextMargin = (int) GalleryUtils.dpToPixel(16);
686b891c6a3739f8c49d42f9db6fc76cb92c7c5f25Chih-Chung Chang
696b891c6a3739f8c49d42f9db6fc76cb92c7c5f25Chih-Chung Chang        mPanel = new NinePatchTexture(context, R.drawable.panel_undo_holo);
706b891c6a3739f8c49d42f9db6fc76cb92c7c5f25Chih-Chung Chang        mUndoText = StringTexture.newInstance(context.getString(R.string.undo),
716b891c6a3739f8c49d42f9db6fc76cb92c7c5f25Chih-Chung Chang                GalleryUtils.dpToPixel(12), GRAY, 0, true);
726b891c6a3739f8c49d42f9db6fc76cb92c7c5f25Chih-Chung Chang        mDeletedText = StringTexture.newInstance(
736b891c6a3739f8c49d42f9db6fc76cb92c7c5f25Chih-Chung Chang                context.getString(R.string.deleted),
746b891c6a3739f8c49d42f9db6fc76cb92c7c5f25Chih-Chung Chang                GalleryUtils.dpToPixel(16), WHITE);
756b891c6a3739f8c49d42f9db6fc76cb92c7c5f25Chih-Chung Chang        mUndoIcon = new ResourceTexture(
766b891c6a3739f8c49d42f9db6fc76cb92c7c5f25Chih-Chung Chang                context, R.drawable.ic_menu_revert_holo_dark);
776b891c6a3739f8c49d42f9db6fc76cb92c7c5f25Chih-Chung Chang        mClickRegion = mBarMargin + mUndoTextMargin + mUndoText.getWidth()
786b891c6a3739f8c49d42f9db6fc76cb92c7c5f25Chih-Chung Chang                + mIconMargin + mIconSize + mSeparatorRightMargin;
796b891c6a3739f8c49d42f9db6fc76cb92c7c5f25Chih-Chung Chang    }
806b891c6a3739f8c49d42f9db6fc76cb92c7c5f25Chih-Chung Chang
816b891c6a3739f8c49d42f9db6fc76cb92c7c5f25Chih-Chung Chang    public void setOnClickListener(OnClickListener listener) {
826b891c6a3739f8c49d42f9db6fc76cb92c7c5f25Chih-Chung Chang        mOnClickListener = listener;
836b891c6a3739f8c49d42f9db6fc76cb92c7c5f25Chih-Chung Chang    }
846b891c6a3739f8c49d42f9db6fc76cb92c7c5f25Chih-Chung Chang
856b891c6a3739f8c49d42f9db6fc76cb92c7c5f25Chih-Chung Chang    @Override
866b891c6a3739f8c49d42f9db6fc76cb92c7c5f25Chih-Chung Chang    protected void onMeasure(int widthSpec, int heightSpec) {
876b891c6a3739f8c49d42f9db6fc76cb92c7c5f25Chih-Chung Chang        setMeasuredSize(0 /* unused */, mBarHeight);
886b891c6a3739f8c49d42f9db6fc76cb92c7c5f25Chih-Chung Chang    }
896b891c6a3739f8c49d42f9db6fc76cb92c7c5f25Chih-Chung Chang
906b891c6a3739f8c49d42f9db6fc76cb92c7c5f25Chih-Chung Chang    @Override
916b891c6a3739f8c49d42f9db6fc76cb92c7c5f25Chih-Chung Chang    protected void render(GLCanvas canvas) {
926b891c6a3739f8c49d42f9db6fc76cb92c7c5f25Chih-Chung Chang        super.render(canvas);
93517e1bd25305d4e82d101a8c06be0119dde2eab3Chih-Chung Chang        advanceAnimation();
94517e1bd25305d4e82d101a8c06be0119dde2eab3Chih-Chung Chang
95517e1bd25305d4e82d101a8c06be0119dde2eab3Chih-Chung Chang        canvas.save(GLCanvas.SAVE_FLAG_ALPHA);
96517e1bd25305d4e82d101a8c06be0119dde2eab3Chih-Chung Chang        canvas.multiplyAlpha(mAlpha);
97517e1bd25305d4e82d101a8c06be0119dde2eab3Chih-Chung Chang
986b891c6a3739f8c49d42f9db6fc76cb92c7c5f25Chih-Chung Chang        int w = getWidth();
996b891c6a3739f8c49d42f9db6fc76cb92c7c5f25Chih-Chung Chang        int h = getHeight();
1006b891c6a3739f8c49d42f9db6fc76cb92c7c5f25Chih-Chung Chang        mPanel.draw(canvas, mBarMargin, 0, w - mBarMargin * 2, mBarHeight);
1016b891c6a3739f8c49d42f9db6fc76cb92c7c5f25Chih-Chung Chang
1026b891c6a3739f8c49d42f9db6fc76cb92c7c5f25Chih-Chung Chang        int x = w - mBarMargin;
1036b891c6a3739f8c49d42f9db6fc76cb92c7c5f25Chih-Chung Chang        int y;
1046b891c6a3739f8c49d42f9db6fc76cb92c7c5f25Chih-Chung Chang
1056b891c6a3739f8c49d42f9db6fc76cb92c7c5f25Chih-Chung Chang        x -= mUndoTextMargin + mUndoText.getWidth();
1066b891c6a3739f8c49d42f9db6fc76cb92c7c5f25Chih-Chung Chang        y = (mBarHeight - mUndoText.getHeight()) / 2;
1076b891c6a3739f8c49d42f9db6fc76cb92c7c5f25Chih-Chung Chang        mUndoText.draw(canvas, x, y);
1086b891c6a3739f8c49d42f9db6fc76cb92c7c5f25Chih-Chung Chang
1096b891c6a3739f8c49d42f9db6fc76cb92c7c5f25Chih-Chung Chang        x -= mIconMargin + mIconSize;
1106b891c6a3739f8c49d42f9db6fc76cb92c7c5f25Chih-Chung Chang        y = (mBarHeight - mIconSize) / 2;
1116b891c6a3739f8c49d42f9db6fc76cb92c7c5f25Chih-Chung Chang        mUndoIcon.draw(canvas, x, y, mIconSize, mIconSize);
1126b891c6a3739f8c49d42f9db6fc76cb92c7c5f25Chih-Chung Chang
1136b891c6a3739f8c49d42f9db6fc76cb92c7c5f25Chih-Chung Chang        x -= mSeparatorRightMargin + mSeparatorWidth;
1146b891c6a3739f8c49d42f9db6fc76cb92c7c5f25Chih-Chung Chang        y = mSeparatorTopMargin;
1156b891c6a3739f8c49d42f9db6fc76cb92c7c5f25Chih-Chung Chang        canvas.fillRect(x, y, mSeparatorWidth,
1166b891c6a3739f8c49d42f9db6fc76cb92c7c5f25Chih-Chung Chang                mBarHeight - mSeparatorTopMargin - mSeparatorBottomMargin, GRAY);
1176b891c6a3739f8c49d42f9db6fc76cb92c7c5f25Chih-Chung Chang
1186b891c6a3739f8c49d42f9db6fc76cb92c7c5f25Chih-Chung Chang        x = mBarMargin + mDeletedTextMargin;
1196b891c6a3739f8c49d42f9db6fc76cb92c7c5f25Chih-Chung Chang        y = (mBarHeight - mDeletedText.getHeight()) / 2;
1206b891c6a3739f8c49d42f9db6fc76cb92c7c5f25Chih-Chung Chang        mDeletedText.draw(canvas, x, y);
121517e1bd25305d4e82d101a8c06be0119dde2eab3Chih-Chung Chang
122517e1bd25305d4e82d101a8c06be0119dde2eab3Chih-Chung Chang        canvas.restore();
1236b891c6a3739f8c49d42f9db6fc76cb92c7c5f25Chih-Chung Chang    }
1246b891c6a3739f8c49d42f9db6fc76cb92c7c5f25Chih-Chung Chang
1256b891c6a3739f8c49d42f9db6fc76cb92c7c5f25Chih-Chung Chang    @Override
1266b891c6a3739f8c49d42f9db6fc76cb92c7c5f25Chih-Chung Chang    protected boolean onTouch(MotionEvent event) {
1276b891c6a3739f8c49d42f9db6fc76cb92c7c5f25Chih-Chung Chang        switch (event.getAction()) {
1286b891c6a3739f8c49d42f9db6fc76cb92c7c5f25Chih-Chung Chang            case MotionEvent.ACTION_DOWN:
1296b891c6a3739f8c49d42f9db6fc76cb92c7c5f25Chih-Chung Chang                mDownOnButton = inUndoButton(event);
1306b891c6a3739f8c49d42f9db6fc76cb92c7c5f25Chih-Chung Chang                break;
1316b891c6a3739f8c49d42f9db6fc76cb92c7c5f25Chih-Chung Chang            case MotionEvent.ACTION_UP:
1326b891c6a3739f8c49d42f9db6fc76cb92c7c5f25Chih-Chung Chang                if (mDownOnButton) {
1336b891c6a3739f8c49d42f9db6fc76cb92c7c5f25Chih-Chung Chang                    if (mOnClickListener != null && inUndoButton(event)) {
1346b891c6a3739f8c49d42f9db6fc76cb92c7c5f25Chih-Chung Chang                        mOnClickListener.onClick(this);
1356b891c6a3739f8c49d42f9db6fc76cb92c7c5f25Chih-Chung Chang                    }
1366b891c6a3739f8c49d42f9db6fc76cb92c7c5f25Chih-Chung Chang                    mDownOnButton = false;
1376b891c6a3739f8c49d42f9db6fc76cb92c7c5f25Chih-Chung Chang                }
1386b891c6a3739f8c49d42f9db6fc76cb92c7c5f25Chih-Chung Chang                break;
1396b891c6a3739f8c49d42f9db6fc76cb92c7c5f25Chih-Chung Chang            case MotionEvent.ACTION_CANCEL:
1406b891c6a3739f8c49d42f9db6fc76cb92c7c5f25Chih-Chung Chang                mDownOnButton = false;
1416b891c6a3739f8c49d42f9db6fc76cb92c7c5f25Chih-Chung Chang                break;
1426b891c6a3739f8c49d42f9db6fc76cb92c7c5f25Chih-Chung Chang        }
1436b891c6a3739f8c49d42f9db6fc76cb92c7c5f25Chih-Chung Chang        return true;
1446b891c6a3739f8c49d42f9db6fc76cb92c7c5f25Chih-Chung Chang    }
1456b891c6a3739f8c49d42f9db6fc76cb92c7c5f25Chih-Chung Chang
1466b891c6a3739f8c49d42f9db6fc76cb92c7c5f25Chih-Chung Chang    // Check if the event is on the right of the separator
1476b891c6a3739f8c49d42f9db6fc76cb92c7c5f25Chih-Chung Chang    private boolean inUndoButton(MotionEvent event) {
1486b891c6a3739f8c49d42f9db6fc76cb92c7c5f25Chih-Chung Chang        float x = event.getX();
1496b891c6a3739f8c49d42f9db6fc76cb92c7c5f25Chih-Chung Chang        float y = event.getY();
1506b891c6a3739f8c49d42f9db6fc76cb92c7c5f25Chih-Chung Chang        int w = getWidth();
1516b891c6a3739f8c49d42f9db6fc76cb92c7c5f25Chih-Chung Chang        int h = getHeight();
1526b891c6a3739f8c49d42f9db6fc76cb92c7c5f25Chih-Chung Chang        return (x >= w - mClickRegion && x < w && y >= 0 && y < h);
1536b891c6a3739f8c49d42f9db6fc76cb92c7c5f25Chih-Chung Chang    }
154517e1bd25305d4e82d101a8c06be0119dde2eab3Chih-Chung Chang
155517e1bd25305d4e82d101a8c06be0119dde2eab3Chih-Chung Chang    ////////////////////////////////////////////////////////////////////////////
156517e1bd25305d4e82d101a8c06be0119dde2eab3Chih-Chung Chang    //  Alpha Animation
157517e1bd25305d4e82d101a8c06be0119dde2eab3Chih-Chung Chang    ////////////////////////////////////////////////////////////////////////////
158517e1bd25305d4e82d101a8c06be0119dde2eab3Chih-Chung Chang
159517e1bd25305d4e82d101a8c06be0119dde2eab3Chih-Chung Chang    private static final long NO_ANIMATION = -1;
160517e1bd25305d4e82d101a8c06be0119dde2eab3Chih-Chung Chang    private static long ANIM_TIME = 200;
161517e1bd25305d4e82d101a8c06be0119dde2eab3Chih-Chung Chang    private long mAnimationStartTime = NO_ANIMATION;
162517e1bd25305d4e82d101a8c06be0119dde2eab3Chih-Chung Chang    private float mFromAlpha, mToAlpha;
163517e1bd25305d4e82d101a8c06be0119dde2eab3Chih-Chung Chang    private float mAlpha;
164517e1bd25305d4e82d101a8c06be0119dde2eab3Chih-Chung Chang
165517e1bd25305d4e82d101a8c06be0119dde2eab3Chih-Chung Chang    private static float getTargetAlpha(int visibility) {
166517e1bd25305d4e82d101a8c06be0119dde2eab3Chih-Chung Chang        return (visibility == VISIBLE) ? 1f : 0f;
167517e1bd25305d4e82d101a8c06be0119dde2eab3Chih-Chung Chang    }
168517e1bd25305d4e82d101a8c06be0119dde2eab3Chih-Chung Chang
169517e1bd25305d4e82d101a8c06be0119dde2eab3Chih-Chung Chang    public void setVisibility(int visibility) {
170517e1bd25305d4e82d101a8c06be0119dde2eab3Chih-Chung Chang        mAlpha = getTargetAlpha(visibility);
171517e1bd25305d4e82d101a8c06be0119dde2eab3Chih-Chung Chang        mAnimationStartTime = NO_ANIMATION;
172517e1bd25305d4e82d101a8c06be0119dde2eab3Chih-Chung Chang        super.setVisibility(visibility);
173517e1bd25305d4e82d101a8c06be0119dde2eab3Chih-Chung Chang        invalidate();
174517e1bd25305d4e82d101a8c06be0119dde2eab3Chih-Chung Chang    }
175517e1bd25305d4e82d101a8c06be0119dde2eab3Chih-Chung Chang
176517e1bd25305d4e82d101a8c06be0119dde2eab3Chih-Chung Chang    public void animateVisibility(int visibility) {
177517e1bd25305d4e82d101a8c06be0119dde2eab3Chih-Chung Chang        float target = getTargetAlpha(visibility);
178517e1bd25305d4e82d101a8c06be0119dde2eab3Chih-Chung Chang        if (mAnimationStartTime == NO_ANIMATION && mAlpha == target) return;
179517e1bd25305d4e82d101a8c06be0119dde2eab3Chih-Chung Chang        if (mAnimationStartTime != NO_ANIMATION && mToAlpha == target) return;
180517e1bd25305d4e82d101a8c06be0119dde2eab3Chih-Chung Chang
181517e1bd25305d4e82d101a8c06be0119dde2eab3Chih-Chung Chang        mFromAlpha = mAlpha;
182517e1bd25305d4e82d101a8c06be0119dde2eab3Chih-Chung Chang        mToAlpha = target;
183517e1bd25305d4e82d101a8c06be0119dde2eab3Chih-Chung Chang        mAnimationStartTime = AnimationTime.startTime();
184517e1bd25305d4e82d101a8c06be0119dde2eab3Chih-Chung Chang
185517e1bd25305d4e82d101a8c06be0119dde2eab3Chih-Chung Chang        super.setVisibility(VISIBLE);
186517e1bd25305d4e82d101a8c06be0119dde2eab3Chih-Chung Chang        invalidate();
187517e1bd25305d4e82d101a8c06be0119dde2eab3Chih-Chung Chang    }
188517e1bd25305d4e82d101a8c06be0119dde2eab3Chih-Chung Chang
189517e1bd25305d4e82d101a8c06be0119dde2eab3Chih-Chung Chang    private void advanceAnimation() {
190517e1bd25305d4e82d101a8c06be0119dde2eab3Chih-Chung Chang        if (mAnimationStartTime == NO_ANIMATION) return;
191517e1bd25305d4e82d101a8c06be0119dde2eab3Chih-Chung Chang
192517e1bd25305d4e82d101a8c06be0119dde2eab3Chih-Chung Chang        float delta = (float) (AnimationTime.get() - mAnimationStartTime) /
193517e1bd25305d4e82d101a8c06be0119dde2eab3Chih-Chung Chang                ANIM_TIME;
194517e1bd25305d4e82d101a8c06be0119dde2eab3Chih-Chung Chang        mAlpha = mFromAlpha + ((mToAlpha > mFromAlpha) ? delta : -delta);
195517e1bd25305d4e82d101a8c06be0119dde2eab3Chih-Chung Chang        mAlpha = Utils.clamp(mAlpha, 0f, 1f);
196517e1bd25305d4e82d101a8c06be0119dde2eab3Chih-Chung Chang
197517e1bd25305d4e82d101a8c06be0119dde2eab3Chih-Chung Chang        if (mAlpha == mToAlpha) {
198517e1bd25305d4e82d101a8c06be0119dde2eab3Chih-Chung Chang            mAnimationStartTime = NO_ANIMATION;
199517e1bd25305d4e82d101a8c06be0119dde2eab3Chih-Chung Chang            if (mAlpha == 0) {
200517e1bd25305d4e82d101a8c06be0119dde2eab3Chih-Chung Chang                super.setVisibility(INVISIBLE);
201517e1bd25305d4e82d101a8c06be0119dde2eab3Chih-Chung Chang            }
202517e1bd25305d4e82d101a8c06be0119dde2eab3Chih-Chung Chang        }
203517e1bd25305d4e82d101a8c06be0119dde2eab3Chih-Chung Chang        invalidate();
204517e1bd25305d4e82d101a8c06be0119dde2eab3Chih-Chung Chang    }
2056b891c6a3739f8c49d42f9db6fc76cb92c7c5f25Chih-Chung Chang}
206