AdapterViewFlipper.java revision aac722a9c0d199c79ae8ce2dd3cce113f01c30b7
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;
282dd2197805edb4d9547b143deef2226413218f4cAdam Cohenimport android.view.RemotableViewMethod;
298a78fd4d9572dff95432fcc4ba0e87563415b728Svetoslav Ganovimport android.view.accessibility.AccessibilityEvent;
308a78fd4d9572dff95432fcc4ba0e87563415b728Svetoslav Ganovimport android.view.accessibility.AccessibilityNodeInfo;
313db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohenimport android.widget.RemoteViews.RemoteView;
323db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen
333db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen/**
343db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen * Simple {@link ViewAnimator} that will animate between two or more views
353db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen * that have been added to it.  Only one child is shown at a time.  If
363db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen * requested, can automatically flip between each child at a regular interval.
373db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen *
383db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen * @attr ref android.R.styleable#AdapterViewFlipper_flipInterval
393db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen * @attr ref android.R.styleable#AdapterViewFlipper_autoStart
403db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen */
413db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen@RemoteView
423db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohenpublic class AdapterViewFlipper extends AdapterViewAnimator {
433db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen    private static final String TAG = "ViewFlipper";
443db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen    private static final boolean LOGD = false;
453db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen
463db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen    private static final int DEFAULT_INTERVAL = 10000;
473db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen
483db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen    private int mFlipInterval = DEFAULT_INTERVAL;
493db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen    private boolean mAutoStart = false;
503db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen
513db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen    private boolean mRunning = false;
523db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen    private boolean mStarted = false;
533db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen    private boolean mVisible = false;
543db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen    private boolean mUserPresent = true;
55a02fdf1ba03fad71cc80a89dfc74b17456d5b4a5Adam Cohen    private boolean mAdvancedByHost = false;
563db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen
573db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen    public AdapterViewFlipper(Context context) {
583db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen        super(context);
593db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen    }
603db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen
613db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen    public AdapterViewFlipper(Context context, AttributeSet attrs) {
623db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen        super(context, attrs);
633db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen
643db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen        TypedArray a = context.obtainStyledAttributes(attrs,
654725660292bcf11c84e9c7da127fd0215fb58e81Adam Cohen                com.android.internal.R.styleable.AdapterViewFlipper);
663db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen        mFlipInterval = a.getInt(
674725660292bcf11c84e9c7da127fd0215fb58e81Adam Cohen                com.android.internal.R.styleable.AdapterViewFlipper_flipInterval, DEFAULT_INTERVAL);
683db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen        mAutoStart = a.getBoolean(
694725660292bcf11c84e9c7da127fd0215fb58e81Adam Cohen                com.android.internal.R.styleable.AdapterViewFlipper_autoStart, false);
701b065cd1401253f999caa5d0ac12909407cef00eAdam Cohen
714725660292bcf11c84e9c7da127fd0215fb58e81Adam Cohen        // A view flipper should cycle through the views
724725660292bcf11c84e9c7da127fd0215fb58e81Adam Cohen        mLoopViews = true;
731b065cd1401253f999caa5d0ac12909407cef00eAdam Cohen
743db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen        a.recycle();
753db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen    }
763db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen
773db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen    private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
783db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen        @Override
793db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen        public void onReceive(Context context, Intent intent) {
803db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen            final String action = intent.getAction();
813db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen            if (Intent.ACTION_SCREEN_OFF.equals(action)) {
823db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen                mUserPresent = false;
833db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen                updateRunning();
843db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen            } else if (Intent.ACTION_USER_PRESENT.equals(action)) {
853db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen                mUserPresent = true;
863db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen                updateRunning(false);
873db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen            }
883db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen        }
893db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen    };
903db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen
913db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen    @Override
923db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen    protected void onAttachedToWindow() {
933db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen        super.onAttachedToWindow();
943db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen
953db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen        // Listen for broadcasts related to user-presence
963db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen        final IntentFilter filter = new IntentFilter();
973db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen        filter.addAction(Intent.ACTION_SCREEN_OFF);
983db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen        filter.addAction(Intent.ACTION_USER_PRESENT);
993db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen        getContext().registerReceiver(mReceiver, filter);
1003db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen
1013db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen        if (mAutoStart) {
1023db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen            // Automatically start when requested
1033db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen            startFlipping();
1043db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen        }
1053db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen    }
1063db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen
1073db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen    @Override
1083db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen    protected void onDetachedFromWindow() {
1093db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen        super.onDetachedFromWindow();
1103db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen        mVisible = false;
1113db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen
1123db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen        getContext().unregisterReceiver(mReceiver);
1133db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen        updateRunning();
1143db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen    }
1153db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen
1163db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen    @Override
1173db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen    protected void onWindowVisibilityChanged(int visibility) {
1183db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen        super.onWindowVisibilityChanged(visibility);
1193db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen        mVisible = (visibility == VISIBLE);
1203db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen        updateRunning(false);
1213db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen    }
1223db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen
1233db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen    @Override
1243db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen    public void setAdapter(Adapter adapter) {
1253db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen        super.setAdapter(adapter);
1263db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen        updateRunning();
1273db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen    }
1283db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen
1293db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen    /**
130aac722a9c0d199c79ae8ce2dd3cce113f01c30b7Philip Milne     * Returns the flip interval, in milliseconds.
1313db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen     *
132aac722a9c0d199c79ae8ce2dd3cce113f01c30b7Philip Milne     * @return the flip interval in milliseconds
133aac722a9c0d199c79ae8ce2dd3cce113f01c30b7Philip Milne     *
134aac722a9c0d199c79ae8ce2dd3cce113f01c30b7Philip Milne     * @see #setFlipInterval(int)
135aac722a9c0d199c79ae8ce2dd3cce113f01c30b7Philip Milne     *
136aac722a9c0d199c79ae8ce2dd3cce113f01c30b7Philip Milne     * @attr ref android.R.styleable#AdapterViewFlipper_flipInterval
137aac722a9c0d199c79ae8ce2dd3cce113f01c30b7Philip Milne     */
138aac722a9c0d199c79ae8ce2dd3cce113f01c30b7Philip Milne    public int getFlipInterval() {
139aac722a9c0d199c79ae8ce2dd3cce113f01c30b7Philip Milne        return mFlipInterval;
140aac722a9c0d199c79ae8ce2dd3cce113f01c30b7Philip Milne    }
141aac722a9c0d199c79ae8ce2dd3cce113f01c30b7Philip Milne
142aac722a9c0d199c79ae8ce2dd3cce113f01c30b7Philip Milne    /**
143aac722a9c0d199c79ae8ce2dd3cce113f01c30b7Philip Milne     * How long to wait before flipping to the next view.
144aac722a9c0d199c79ae8ce2dd3cce113f01c30b7Philip Milne     *
145aac722a9c0d199c79ae8ce2dd3cce113f01c30b7Philip Milne     * @param flipInterval flip interval in milliseconds
146aac722a9c0d199c79ae8ce2dd3cce113f01c30b7Philip Milne     *
147aac722a9c0d199c79ae8ce2dd3cce113f01c30b7Philip Milne     * @see #getFlipInterval()
148aac722a9c0d199c79ae8ce2dd3cce113f01c30b7Philip Milne     *
149aac722a9c0d199c79ae8ce2dd3cce113f01c30b7Philip Milne     * @attr ref android.R.styleable#AdapterViewFlipper_flipInterval
1503db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen     */
151aac722a9c0d199c79ae8ce2dd3cce113f01c30b7Philip Milne    public void setFlipInterval(int flipInterval) {
152aac722a9c0d199c79ae8ce2dd3cce113f01c30b7Philip Milne        mFlipInterval = flipInterval;
1533db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen    }
1543db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen
1553db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen    /**
1563db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen     * Start a timer to cycle through child views
1573db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen     */
1583db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen    public void startFlipping() {
1593db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen        mStarted = true;
1603db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen        updateRunning();
1613db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen    }
1623db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen
1633db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen    /**
1643db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen     * No more flips
1653db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen     */
1663db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen    public void stopFlipping() {
1673db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen        mStarted = false;
1683db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen        updateRunning();
1693db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen    }
1703db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen
1713db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen    /**
172b04f7ad90b7d5d5e0998e3b56960004cf56e6e8fAdam Cohen    * {@inheritDoc}
173b04f7ad90b7d5d5e0998e3b56960004cf56e6e8fAdam Cohen    */
174b04f7ad90b7d5d5e0998e3b56960004cf56e6e8fAdam Cohen   @Override
175b04f7ad90b7d5d5e0998e3b56960004cf56e6e8fAdam Cohen   @RemotableViewMethod
176b04f7ad90b7d5d5e0998e3b56960004cf56e6e8fAdam Cohen   public void showNext() {
177b04f7ad90b7d5d5e0998e3b56960004cf56e6e8fAdam Cohen       // if the flipper is currently flipping automatically, and showNext() is called
178b04f7ad90b7d5d5e0998e3b56960004cf56e6e8fAdam Cohen       // we should we should make sure to reset the timer
179b04f7ad90b7d5d5e0998e3b56960004cf56e6e8fAdam Cohen       if (mRunning) {
180b04f7ad90b7d5d5e0998e3b56960004cf56e6e8fAdam Cohen           mHandler.removeMessages(FLIP_MSG);
181b04f7ad90b7d5d5e0998e3b56960004cf56e6e8fAdam Cohen           Message msg = mHandler.obtainMessage(FLIP_MSG);
182b04f7ad90b7d5d5e0998e3b56960004cf56e6e8fAdam Cohen           mHandler.sendMessageDelayed(msg, mFlipInterval);
183b04f7ad90b7d5d5e0998e3b56960004cf56e6e8fAdam Cohen       }
184b04f7ad90b7d5d5e0998e3b56960004cf56e6e8fAdam Cohen       super.showNext();
185b04f7ad90b7d5d5e0998e3b56960004cf56e6e8fAdam Cohen   }
186b04f7ad90b7d5d5e0998e3b56960004cf56e6e8fAdam Cohen
187b04f7ad90b7d5d5e0998e3b56960004cf56e6e8fAdam Cohen   /**
188b04f7ad90b7d5d5e0998e3b56960004cf56e6e8fAdam Cohen    * {@inheritDoc}
189b04f7ad90b7d5d5e0998e3b56960004cf56e6e8fAdam Cohen    */
190b04f7ad90b7d5d5e0998e3b56960004cf56e6e8fAdam Cohen   @Override
191b04f7ad90b7d5d5e0998e3b56960004cf56e6e8fAdam Cohen   @RemotableViewMethod
192b04f7ad90b7d5d5e0998e3b56960004cf56e6e8fAdam Cohen   public void showPrevious() {
193b04f7ad90b7d5d5e0998e3b56960004cf56e6e8fAdam Cohen       // if the flipper is currently flipping automatically, and showPrevious() is called
194b04f7ad90b7d5d5e0998e3b56960004cf56e6e8fAdam Cohen       // we should we should make sure to reset the timer
195b04f7ad90b7d5d5e0998e3b56960004cf56e6e8fAdam Cohen       if (mRunning) {
196b04f7ad90b7d5d5e0998e3b56960004cf56e6e8fAdam Cohen           mHandler.removeMessages(FLIP_MSG);
197b04f7ad90b7d5d5e0998e3b56960004cf56e6e8fAdam Cohen           Message msg = mHandler.obtainMessage(FLIP_MSG);
198b04f7ad90b7d5d5e0998e3b56960004cf56e6e8fAdam Cohen           mHandler.sendMessageDelayed(msg, mFlipInterval);
199b04f7ad90b7d5d5e0998e3b56960004cf56e6e8fAdam Cohen       }
200b04f7ad90b7d5d5e0998e3b56960004cf56e6e8fAdam Cohen       super.showPrevious();
201b04f7ad90b7d5d5e0998e3b56960004cf56e6e8fAdam Cohen   }
202b04f7ad90b7d5d5e0998e3b56960004cf56e6e8fAdam Cohen
203b04f7ad90b7d5d5e0998e3b56960004cf56e6e8fAdam Cohen    /**
2043db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen     * Internal method to start or stop dispatching flip {@link Message} based
2053db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen     * on {@link #mRunning} and {@link #mVisible} state.
2063db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen     */
2073db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen    private void updateRunning() {
2083db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen        // by default when we update running, we want the
2093db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen        // current view to animate in
2103db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen        updateRunning(true);
2113db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen    }
2123db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen
2133db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen    /**
2143db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen     * Internal method to start or stop dispatching flip {@link Message} based
2153db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen     * on {@link #mRunning} and {@link #mVisible} state.
2163db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen     *
2173db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen     * @param flipNow Determines whether or not to execute the animation now, in
2183db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen     *            addition to queuing future flips. If omitted, defaults to
2193db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen     *            true.
2203db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen     */
2213db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen    private void updateRunning(boolean flipNow) {
222a02fdf1ba03fad71cc80a89dfc74b17456d5b4a5Adam Cohen        boolean running = !mAdvancedByHost && mVisible && mStarted && mUserPresent
223a02fdf1ba03fad71cc80a89dfc74b17456d5b4a5Adam Cohen                && mAdapter != null;
2243db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen        if (running != mRunning) {
2253db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen            if (running) {
2263db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen                showOnly(mWhichChild, flipNow);
2273db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen                Message msg = mHandler.obtainMessage(FLIP_MSG);
2283db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen                mHandler.sendMessageDelayed(msg, mFlipInterval);
2293db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen            } else {
2303db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen                mHandler.removeMessages(FLIP_MSG);
2313db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen            }
2323db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen            mRunning = running;
2333db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen        }
2343db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen        if (LOGD) {
2353db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen            Log.d(TAG, "updateRunning() mVisible=" + mVisible + ", mStarted=" + mStarted
2363db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen                    + ", mUserPresent=" + mUserPresent + ", mRunning=" + mRunning);
2373db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen        }
2383db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen    }
2393db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen
2403db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen    /**
2413db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen     * Returns true if the child views are flipping.
2423db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen     */
2433db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen    public boolean isFlipping() {
2443db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen        return mStarted;
2453db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen    }
2463db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen
2473db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen    /**
2483db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen     * Set if this view automatically calls {@link #startFlipping()} when it
2493db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen     * becomes attached to a window.
2503db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen     */
2513db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen    public void setAutoStart(boolean autoStart) {
2523db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen        mAutoStart = autoStart;
2533db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen    }
2543db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen
2553db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen    /**
2563db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen     * Returns true if this view automatically calls {@link #startFlipping()}
2573db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen     * when it becomes attached to a window.
2583db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen     */
2593db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen    public boolean isAutoStart() {
2603db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen        return mAutoStart;
2613db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen    }
2623db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen
2633db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen    private final int FLIP_MSG = 1;
2643db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen
2653db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen    private final Handler mHandler = new Handler() {
2663db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen        @Override
2673db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen        public void handleMessage(Message msg) {
2683db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen            if (msg.what == FLIP_MSG) {
2693db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen                if (mRunning) {
2703db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen                    showNext();
2713db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen                }
2723db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen            }
2733db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen        }
2743db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen    };
275a02fdf1ba03fad71cc80a89dfc74b17456d5b4a5Adam Cohen
2760e2de6d7187ef67ec00a2f2544450caa4a239c39Adam Cohen    /**
2770e2de6d7187ef67ec00a2f2544450caa4a239c39Adam Cohen     * Called by an {@link android.appwidget.AppWidgetHost} to indicate that it will be
2780e2de6d7187ef67ec00a2f2544450caa4a239c39Adam Cohen     * automatically advancing the views of this {@link AdapterViewFlipper} by calling
2790e2de6d7187ef67ec00a2f2544450caa4a239c39Adam Cohen     * {@link AdapterViewFlipper#advance()} at some point in the future. This allows
2800e2de6d7187ef67ec00a2f2544450caa4a239c39Adam Cohen     * {@link AdapterViewFlipper} to prepare by no longer Advancing its children.
2810e2de6d7187ef67ec00a2f2544450caa4a239c39Adam Cohen     */
282a02fdf1ba03fad71cc80a89dfc74b17456d5b4a5Adam Cohen    @Override
2830e2de6d7187ef67ec00a2f2544450caa4a239c39Adam Cohen    public void fyiWillBeAdvancedByHostKThx() {
284a02fdf1ba03fad71cc80a89dfc74b17456d5b4a5Adam Cohen        mAdvancedByHost = true;
285a02fdf1ba03fad71cc80a89dfc74b17456d5b4a5Adam Cohen        updateRunning(false);
286a02fdf1ba03fad71cc80a89dfc74b17456d5b4a5Adam Cohen    }
2878a78fd4d9572dff95432fcc4ba0e87563415b728Svetoslav Ganov
2888a78fd4d9572dff95432fcc4ba0e87563415b728Svetoslav Ganov    @Override
2898a78fd4d9572dff95432fcc4ba0e87563415b728Svetoslav Ganov    public void onInitializeAccessibilityEvent(AccessibilityEvent event) {
2908a78fd4d9572dff95432fcc4ba0e87563415b728Svetoslav Ganov        super.onInitializeAccessibilityEvent(event);
2918a78fd4d9572dff95432fcc4ba0e87563415b728Svetoslav Ganov        event.setClassName(AdapterViewFlipper.class.getName());
2928a78fd4d9572dff95432fcc4ba0e87563415b728Svetoslav Ganov    }
2938a78fd4d9572dff95432fcc4ba0e87563415b728Svetoslav Ganov
2948a78fd4d9572dff95432fcc4ba0e87563415b728Svetoslav Ganov    @Override
2958a78fd4d9572dff95432fcc4ba0e87563415b728Svetoslav Ganov    public void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info) {
2968a78fd4d9572dff95432fcc4ba0e87563415b728Svetoslav Ganov        super.onInitializeAccessibilityNodeInfo(info);
2978a78fd4d9572dff95432fcc4ba0e87563415b728Svetoslav Ganov        info.setClassName(AdapterViewFlipper.class.getName());
2988a78fd4d9572dff95432fcc4ba0e87563415b728Svetoslav Ganov    }
2993db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen}
300