AdapterViewFlipper.java revision 3db40678d33c2b5f90c380966d36b3e10ed11f05
13db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen/*
23db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen * Copyright (C) 2010 The Android Open Source Project
33db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen *
43db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen * Licensed under the Apache License, Version 2.0 (the "License");
53db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen * you may not use this file except in compliance with the License.
63db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen * You may obtain a copy of the License at
73db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen *
83db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen *      http://www.apache.org/licenses/LICENSE-2.0
93db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen *
103db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen * Unless required by applicable law or agreed to in writing, software
113db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen * distributed under the License is distributed on an "AS IS" BASIS,
123db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
133db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen * See the License for the specific language governing permissions and
143db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen * limitations under the License.
153db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen */
163db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen
173db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohenpackage android.widget;
183db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen
193db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohenimport android.content.BroadcastReceiver;
203db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohenimport android.content.Context;
213db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohenimport android.content.Intent;
223db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohenimport android.content.IntentFilter;
233db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohenimport android.content.res.TypedArray;
243db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohenimport android.os.Handler;
253db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohenimport android.os.Message;
263db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohenimport android.util.AttributeSet;
273db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohenimport android.util.Log;
283db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohenimport android.view.animation.AlphaAnimation;
293db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohenimport android.view.animation.Animation;
303db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohenimport android.widget.RemoteViews.RemoteView;
313db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen
323db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen/**
333db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen * Simple {@link ViewAnimator} that will animate between two or more views
343db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen * that have been added to it.  Only one child is shown at a time.  If
353db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen * requested, can automatically flip between each child at a regular interval.
363db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen *
373db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen * @attr ref android.R.styleable#AdapterViewFlipper_flipInterval
383db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen * @attr ref android.R.styleable#AdapterViewFlipper_autoStart
393db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen */
403db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen@RemoteView
413db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohenpublic class AdapterViewFlipper extends AdapterViewAnimator {
423db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen    private static final String TAG = "ViewFlipper";
433db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen    private static final boolean LOGD = false;
443db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen
453db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen    private static final int DEFAULT_INTERVAL = 10000;
463db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen    private static final int DEFAULT_ANIMATION_DURATION = 200;
473db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen
483db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen    private int mFlipInterval = DEFAULT_INTERVAL;
493db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen    private int mAnimationDuration = DEFAULT_ANIMATION_DURATION;
503db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen    private boolean mAutoStart = false;
513db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen
523db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen    private boolean mRunning = false;
533db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen    private boolean mStarted = false;
543db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen    private boolean mVisible = false;
553db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen    private boolean mUserPresent = true;
563db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen
573db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen    public AdapterViewFlipper(Context context) {
583db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen        super(context);
593db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen        initDefaultAnimations();
603db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen    }
613db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen
623db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen    public AdapterViewFlipper(Context context, AttributeSet attrs) {
633db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen        super(context, attrs);
643db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen
653db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen        TypedArray a = context.obtainStyledAttributes(attrs,
663db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen                com.android.internal.R.styleable.ViewFlipper);
673db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen        mFlipInterval = a.getInt(
683db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen                com.android.internal.R.styleable.ViewFlipper_flipInterval, DEFAULT_INTERVAL);
693db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen        mAutoStart = a.getBoolean(
703db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen                com.android.internal.R.styleable.ViewFlipper_autoStart, false);
713db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen        a.recycle();
723db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen        initDefaultAnimations();
733db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen    }
743db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen
753db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen    private void initDefaultAnimations() {
763db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen        // Set the default animations to be fade in/out
773db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen        if (mInAnimation == null) {
783db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen            mInAnimation = new AlphaAnimation(0.0f, 1.0f);
793db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen            mInAnimation.setDuration(mAnimationDuration);
803db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen        }
813db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen        if (mOutAnimation == null) {
823db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen            mOutAnimation = new AlphaAnimation(1.0f, 0.0f);
833db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen            mOutAnimation.setDuration(mAnimationDuration);
843db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen        }
853db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen    }
863db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen
873db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen    private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
883db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen        @Override
893db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen        public void onReceive(Context context, Intent intent) {
903db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen            final String action = intent.getAction();
913db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen            if (Intent.ACTION_SCREEN_OFF.equals(action)) {
923db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen                mUserPresent = false;
933db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen                updateRunning();
943db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen            } else if (Intent.ACTION_USER_PRESENT.equals(action)) {
953db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen                mUserPresent = true;
963db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen                updateRunning(false);
973db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen            }
983db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen        }
993db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen    };
1003db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen
1013db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen    @Override
1023db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen    protected void onAttachedToWindow() {
1033db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen        super.onAttachedToWindow();
1043db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen
1053db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen        // Listen for broadcasts related to user-presence
1063db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen        final IntentFilter filter = new IntentFilter();
1073db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen        filter.addAction(Intent.ACTION_SCREEN_OFF);
1083db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen        filter.addAction(Intent.ACTION_USER_PRESENT);
1093db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen        getContext().registerReceiver(mReceiver, filter);
1103db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen
1113db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen        if (mAutoStart) {
1123db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen            // Automatically start when requested
1133db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen            startFlipping();
1143db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen        }
1153db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen    }
1163db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen
1173db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen    @Override
1183db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen    protected void onDetachedFromWindow() {
1193db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen        super.onDetachedFromWindow();
1203db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen        mVisible = false;
1213db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen
1223db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen        getContext().unregisterReceiver(mReceiver);
1233db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen        updateRunning();
1243db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen    }
1253db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen
1263db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen    @Override
1273db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen    protected void onWindowVisibilityChanged(int visibility) {
1283db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen        super.onWindowVisibilityChanged(visibility);
1293db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen        mVisible = (visibility == VISIBLE);
1303db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen        updateRunning(false);
1313db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen    }
1323db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen
1333db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen    @Override
1343db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen    public void setAdapter(Adapter adapter) {
1353db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen        super.setAdapter(adapter);
1363db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen        updateRunning();
1373db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen    }
1383db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen
1393db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen    /**
1403db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen     * How long to wait before flipping to the next view
1413db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen     *
1423db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen     * @param milliseconds
1433db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen     *            time in milliseconds
1443db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen     */
1453db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen    public void setFlipInterval(int milliseconds) {
1463db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen        mFlipInterval = milliseconds;
1473db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen    }
1483db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen
1493db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen    /**
1503db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen     * Start a timer to cycle through child views
1513db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen     */
1523db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen    public void startFlipping() {
1533db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen        mStarted = true;
1543db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen        updateRunning();
1553db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen    }
1563db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen
1573db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen    /**
1583db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen     * No more flips
1593db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen     */
1603db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen    public void stopFlipping() {
1613db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen        mStarted = false;
1623db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen        updateRunning();
1633db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen    }
1643db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen
1653db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen    /**
1663db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen     * Internal method to start or stop dispatching flip {@link Message} based
1673db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen     * on {@link #mRunning} and {@link #mVisible} state.
1683db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen     */
1693db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen    private void updateRunning() {
1703db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen        // by default when we update running, we want the
1713db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen        // current view to animate in
1723db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen        updateRunning(true);
1733db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen    }
1743db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen
1753db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen    /**
1763db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen     * Internal method to start or stop dispatching flip {@link Message} based
1773db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen     * on {@link #mRunning} and {@link #mVisible} state.
1783db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen     *
1793db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen     * @param flipNow Determines whether or not to execute the animation now, in
1803db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen     *            addition to queuing future flips. If omitted, defaults to
1813db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen     *            true.
1823db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen     */
1833db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen    private void updateRunning(boolean flipNow) {
1843db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen        boolean running = mVisible && mStarted && mUserPresent && mAdapter != null;
1853db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen        if (running != mRunning) {
1863db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen            if (running) {
1873db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen                showOnly(mWhichChild, flipNow);
1883db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen                Message msg = mHandler.obtainMessage(FLIP_MSG);
1893db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen                mHandler.sendMessageDelayed(msg, mFlipInterval);
1903db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen            } else {
1913db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen                mHandler.removeMessages(FLIP_MSG);
1923db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen            }
1933db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen            mRunning = running;
1943db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen        }
1953db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen        if (LOGD) {
1963db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen            Log.d(TAG, "updateRunning() mVisible=" + mVisible + ", mStarted=" + mStarted
1973db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen                    + ", mUserPresent=" + mUserPresent + ", mRunning=" + mRunning);
1983db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen        }
1993db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen    }
2003db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen
2013db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen    /**
2023db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen     * Returns true if the child views are flipping.
2033db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen     */
2043db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen    public boolean isFlipping() {
2053db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen        return mStarted;
2063db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen    }
2073db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen
2083db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen    /**
2093db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen     * Set if this view automatically calls {@link #startFlipping()} when it
2103db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen     * becomes attached to a window.
2113db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen     */
2123db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen    public void setAutoStart(boolean autoStart) {
2133db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen        mAutoStart = autoStart;
2143db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen    }
2153db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen
2163db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen    /**
2173db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen     * Returns true if this view automatically calls {@link #startFlipping()}
2183db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen     * when it becomes attached to a window.
2193db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen     */
2203db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen    public boolean isAutoStart() {
2213db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen        return mAutoStart;
2223db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen    }
2233db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen
2243db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen    private final int FLIP_MSG = 1;
2253db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen
2263db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen    private final Handler mHandler = new Handler() {
2273db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen        @Override
2283db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen        public void handleMessage(Message msg) {
2293db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen            if (msg.what == FLIP_MSG) {
2303db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen                if (mRunning) {
2313db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen                    showNext();
2323db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen                    msg = obtainMessage(FLIP_MSG);
2333db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen                    sendMessageDelayed(msg, mFlipInterval);
2343db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen                }
2353db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen            }
2363db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen        }
2373db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen    };
2383db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen}
239