19066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/* 29066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Copyright (C) 2006 The Android Open Source Project 39066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 49066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License"); 59066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * you may not use this file except in compliance with the License. 69066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * You may obtain a copy of the License at 79066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 89066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 99066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Unless required by applicable law or agreed to in writing, software 119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * See the License for the specific language governing permissions and 149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * limitations under the License. 159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpackage android.widget; 189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 191162fd77a8ff8467c96204c00bcaf941aef6aa85Jeff Sharkeyimport android.content.BroadcastReceiver; 209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.Context; 211162fd77a8ff8467c96204c00bcaf941aef6aa85Jeff Sharkeyimport android.content.Intent; 221162fd77a8ff8467c96204c00bcaf941aef6aa85Jeff Sharkeyimport android.content.IntentFilter; 239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.res.TypedArray; 249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.Handler; 259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.Message; 269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.util.AttributeSet; 271162fd77a8ff8467c96204c00bcaf941aef6aa85Jeff Sharkeyimport android.util.Log; 289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.widget.RemoteViews.RemoteView; 299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/** 319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Simple {@link ViewAnimator} that will animate between two or more views 329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * that have been added to it. Only one child is shown at a time. If 339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * requested, can automatically flip between each child at a regular interval. 349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @attr ref android.R.styleable#ViewFlipper_flipInterval 361162fd77a8ff8467c96204c00bcaf941aef6aa85Jeff Sharkey * @attr ref android.R.styleable#ViewFlipper_autoStart 379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 381162fd77a8ff8467c96204c00bcaf941aef6aa85Jeff Sharkey@RemoteView 399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpublic class ViewFlipper extends ViewAnimator { 401162fd77a8ff8467c96204c00bcaf941aef6aa85Jeff Sharkey private static final String TAG = "ViewFlipper"; 412b95c2413838c2e2b127ebab8fb4fead7d52e460Jeff Sharkey private static final boolean LOGD = false; 421162fd77a8ff8467c96204c00bcaf941aef6aa85Jeff Sharkey 431162fd77a8ff8467c96204c00bcaf941aef6aa85Jeff Sharkey private static final int DEFAULT_INTERVAL = 3000; 441162fd77a8ff8467c96204c00bcaf941aef6aa85Jeff Sharkey 451162fd77a8ff8467c96204c00bcaf941aef6aa85Jeff Sharkey private int mFlipInterval = DEFAULT_INTERVAL; 461162fd77a8ff8467c96204c00bcaf941aef6aa85Jeff Sharkey private boolean mAutoStart = false; 471162fd77a8ff8467c96204c00bcaf941aef6aa85Jeff Sharkey 481162fd77a8ff8467c96204c00bcaf941aef6aa85Jeff Sharkey private boolean mRunning = false; 491162fd77a8ff8467c96204c00bcaf941aef6aa85Jeff Sharkey private boolean mStarted = false; 501162fd77a8ff8467c96204c00bcaf941aef6aa85Jeff Sharkey private boolean mVisible = false; 511162fd77a8ff8467c96204c00bcaf941aef6aa85Jeff Sharkey private boolean mUserPresent = true; 529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public ViewFlipper(Context context) { 549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project super(context); 559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public ViewFlipper(Context context, AttributeSet attrs) { 589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project super(context, attrs); 599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project TypedArray a = context.obtainStyledAttributes(attrs, 619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project com.android.internal.R.styleable.ViewFlipper); 621162fd77a8ff8467c96204c00bcaf941aef6aa85Jeff Sharkey mFlipInterval = a.getInt( 631162fd77a8ff8467c96204c00bcaf941aef6aa85Jeff Sharkey com.android.internal.R.styleable.ViewFlipper_flipInterval, DEFAULT_INTERVAL); 641162fd77a8ff8467c96204c00bcaf941aef6aa85Jeff Sharkey mAutoStart = a.getBoolean( 651162fd77a8ff8467c96204c00bcaf941aef6aa85Jeff Sharkey com.android.internal.R.styleable.ViewFlipper_autoStart, false); 669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project a.recycle(); 679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 691162fd77a8ff8467c96204c00bcaf941aef6aa85Jeff Sharkey private final BroadcastReceiver mReceiver = new BroadcastReceiver() { 701162fd77a8ff8467c96204c00bcaf941aef6aa85Jeff Sharkey @Override 711162fd77a8ff8467c96204c00bcaf941aef6aa85Jeff Sharkey public void onReceive(Context context, Intent intent) { 721162fd77a8ff8467c96204c00bcaf941aef6aa85Jeff Sharkey final String action = intent.getAction(); 731162fd77a8ff8467c96204c00bcaf941aef6aa85Jeff Sharkey if (Intent.ACTION_SCREEN_OFF.equals(action)) { 741162fd77a8ff8467c96204c00bcaf941aef6aa85Jeff Sharkey mUserPresent = false; 751162fd77a8ff8467c96204c00bcaf941aef6aa85Jeff Sharkey updateRunning(); 761162fd77a8ff8467c96204c00bcaf941aef6aa85Jeff Sharkey } else if (Intent.ACTION_USER_PRESENT.equals(action)) { 771162fd77a8ff8467c96204c00bcaf941aef6aa85Jeff Sharkey mUserPresent = true; 78f70036bc91e93cf6834c835beb832861c0dbd9dbMason Tang updateRunning(false); 791162fd77a8ff8467c96204c00bcaf941aef6aa85Jeff Sharkey } 801162fd77a8ff8467c96204c00bcaf941aef6aa85Jeff Sharkey } 811162fd77a8ff8467c96204c00bcaf941aef6aa85Jeff Sharkey }; 821162fd77a8ff8467c96204c00bcaf941aef6aa85Jeff Sharkey 831162fd77a8ff8467c96204c00bcaf941aef6aa85Jeff Sharkey @Override 841162fd77a8ff8467c96204c00bcaf941aef6aa85Jeff Sharkey protected void onAttachedToWindow() { 851162fd77a8ff8467c96204c00bcaf941aef6aa85Jeff Sharkey super.onAttachedToWindow(); 861162fd77a8ff8467c96204c00bcaf941aef6aa85Jeff Sharkey 871162fd77a8ff8467c96204c00bcaf941aef6aa85Jeff Sharkey // Listen for broadcasts related to user-presence 881162fd77a8ff8467c96204c00bcaf941aef6aa85Jeff Sharkey final IntentFilter filter = new IntentFilter(); 891162fd77a8ff8467c96204c00bcaf941aef6aa85Jeff Sharkey filter.addAction(Intent.ACTION_SCREEN_OFF); 901162fd77a8ff8467c96204c00bcaf941aef6aa85Jeff Sharkey filter.addAction(Intent.ACTION_USER_PRESENT); 911162fd77a8ff8467c96204c00bcaf941aef6aa85Jeff Sharkey getContext().registerReceiver(mReceiver, filter); 921162fd77a8ff8467c96204c00bcaf941aef6aa85Jeff Sharkey 931162fd77a8ff8467c96204c00bcaf941aef6aa85Jeff Sharkey if (mAutoStart) { 941162fd77a8ff8467c96204c00bcaf941aef6aa85Jeff Sharkey // Automatically start when requested 951162fd77a8ff8467c96204c00bcaf941aef6aa85Jeff Sharkey startFlipping(); 961162fd77a8ff8467c96204c00bcaf941aef6aa85Jeff Sharkey } 971162fd77a8ff8467c96204c00bcaf941aef6aa85Jeff Sharkey } 981162fd77a8ff8467c96204c00bcaf941aef6aa85Jeff Sharkey 991162fd77a8ff8467c96204c00bcaf941aef6aa85Jeff Sharkey @Override 1001162fd77a8ff8467c96204c00bcaf941aef6aa85Jeff Sharkey protected void onDetachedFromWindow() { 1011162fd77a8ff8467c96204c00bcaf941aef6aa85Jeff Sharkey super.onDetachedFromWindow(); 1021162fd77a8ff8467c96204c00bcaf941aef6aa85Jeff Sharkey mVisible = false; 1031162fd77a8ff8467c96204c00bcaf941aef6aa85Jeff Sharkey 1041162fd77a8ff8467c96204c00bcaf941aef6aa85Jeff Sharkey getContext().unregisterReceiver(mReceiver); 1051162fd77a8ff8467c96204c00bcaf941aef6aa85Jeff Sharkey updateRunning(); 1061162fd77a8ff8467c96204c00bcaf941aef6aa85Jeff Sharkey } 1071162fd77a8ff8467c96204c00bcaf941aef6aa85Jeff Sharkey 1081162fd77a8ff8467c96204c00bcaf941aef6aa85Jeff Sharkey @Override 1091162fd77a8ff8467c96204c00bcaf941aef6aa85Jeff Sharkey protected void onWindowVisibilityChanged(int visibility) { 1101162fd77a8ff8467c96204c00bcaf941aef6aa85Jeff Sharkey super.onWindowVisibilityChanged(visibility); 1111162fd77a8ff8467c96204c00bcaf941aef6aa85Jeff Sharkey mVisible = visibility == VISIBLE; 112f70036bc91e93cf6834c835beb832861c0dbd9dbMason Tang updateRunning(false); 1131162fd77a8ff8467c96204c00bcaf941aef6aa85Jeff Sharkey } 1141162fd77a8ff8467c96204c00bcaf941aef6aa85Jeff Sharkey 1159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * How long to wait before flipping to the next view 1171162fd77a8ff8467c96204c00bcaf941aef6aa85Jeff Sharkey * 1189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param milliseconds 1199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * time in milliseconds 1209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @android.view.RemotableViewMethod 1229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void setFlipInterval(int milliseconds) { 1239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mFlipInterval = milliseconds; 1249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Start a timer to cycle through child views 1289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void startFlipping() { 1301162fd77a8ff8467c96204c00bcaf941aef6aa85Jeff Sharkey mStarted = true; 1311162fd77a8ff8467c96204c00bcaf941aef6aa85Jeff Sharkey updateRunning(); 1329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * No more flips 1369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void stopFlipping() { 1381162fd77a8ff8467c96204c00bcaf941aef6aa85Jeff Sharkey mStarted = false; 1391162fd77a8ff8467c96204c00bcaf941aef6aa85Jeff Sharkey updateRunning(); 1401162fd77a8ff8467c96204c00bcaf941aef6aa85Jeff Sharkey } 1411162fd77a8ff8467c96204c00bcaf941aef6aa85Jeff Sharkey 1421162fd77a8ff8467c96204c00bcaf941aef6aa85Jeff Sharkey /** 1431162fd77a8ff8467c96204c00bcaf941aef6aa85Jeff Sharkey * Internal method to start or stop dispatching flip {@link Message} based 1441162fd77a8ff8467c96204c00bcaf941aef6aa85Jeff Sharkey * on {@link #mRunning} and {@link #mVisible} state. 1451162fd77a8ff8467c96204c00bcaf941aef6aa85Jeff Sharkey */ 1461162fd77a8ff8467c96204c00bcaf941aef6aa85Jeff Sharkey private void updateRunning() { 147f70036bc91e93cf6834c835beb832861c0dbd9dbMason Tang updateRunning(true); 148f70036bc91e93cf6834c835beb832861c0dbd9dbMason Tang } 149f70036bc91e93cf6834c835beb832861c0dbd9dbMason Tang 150f70036bc91e93cf6834c835beb832861c0dbd9dbMason Tang /** 151f70036bc91e93cf6834c835beb832861c0dbd9dbMason Tang * Internal method to start or stop dispatching flip {@link Message} based 152f70036bc91e93cf6834c835beb832861c0dbd9dbMason Tang * on {@link #mRunning} and {@link #mVisible} state. 153f70036bc91e93cf6834c835beb832861c0dbd9dbMason Tang * 154f70036bc91e93cf6834c835beb832861c0dbd9dbMason Tang * @param flipNow Determines whether or not to execute the animation now, in 155f70036bc91e93cf6834c835beb832861c0dbd9dbMason Tang * addition to queuing future flips. If omitted, defaults to 156f70036bc91e93cf6834c835beb832861c0dbd9dbMason Tang * true. 157f70036bc91e93cf6834c835beb832861c0dbd9dbMason Tang */ 158f70036bc91e93cf6834c835beb832861c0dbd9dbMason Tang private void updateRunning(boolean flipNow) { 1591162fd77a8ff8467c96204c00bcaf941aef6aa85Jeff Sharkey boolean running = mVisible && mStarted && mUserPresent; 1601162fd77a8ff8467c96204c00bcaf941aef6aa85Jeff Sharkey if (running != mRunning) { 1611162fd77a8ff8467c96204c00bcaf941aef6aa85Jeff Sharkey if (running) { 162f70036bc91e93cf6834c835beb832861c0dbd9dbMason Tang showOnly(mWhichChild, flipNow); 1631162fd77a8ff8467c96204c00bcaf941aef6aa85Jeff Sharkey Message msg = mHandler.obtainMessage(FLIP_MSG); 1641162fd77a8ff8467c96204c00bcaf941aef6aa85Jeff Sharkey mHandler.sendMessageDelayed(msg, mFlipInterval); 1651162fd77a8ff8467c96204c00bcaf941aef6aa85Jeff Sharkey } else { 1661162fd77a8ff8467c96204c00bcaf941aef6aa85Jeff Sharkey mHandler.removeMessages(FLIP_MSG); 1671162fd77a8ff8467c96204c00bcaf941aef6aa85Jeff Sharkey } 1681162fd77a8ff8467c96204c00bcaf941aef6aa85Jeff Sharkey mRunning = running; 1691162fd77a8ff8467c96204c00bcaf941aef6aa85Jeff Sharkey } 1701162fd77a8ff8467c96204c00bcaf941aef6aa85Jeff Sharkey if (LOGD) { 1711162fd77a8ff8467c96204c00bcaf941aef6aa85Jeff Sharkey Log.d(TAG, "updateRunning() mVisible=" + mVisible + ", mStarted=" + mStarted 1721162fd77a8ff8467c96204c00bcaf941aef6aa85Jeff Sharkey + ", mUserPresent=" + mUserPresent + ", mRunning=" + mRunning); 1731162fd77a8ff8467c96204c00bcaf941aef6aa85Jeff Sharkey } 1749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Returns true if the child views are flipping. 1789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean isFlipping() { 1801162fd77a8ff8467c96204c00bcaf941aef6aa85Jeff Sharkey return mStarted; 1811162fd77a8ff8467c96204c00bcaf941aef6aa85Jeff Sharkey } 1821162fd77a8ff8467c96204c00bcaf941aef6aa85Jeff Sharkey 1831162fd77a8ff8467c96204c00bcaf941aef6aa85Jeff Sharkey /** 1841162fd77a8ff8467c96204c00bcaf941aef6aa85Jeff Sharkey * Set if this view automatically calls {@link #startFlipping()} when it 1851162fd77a8ff8467c96204c00bcaf941aef6aa85Jeff Sharkey * becomes attached to a window. 1861162fd77a8ff8467c96204c00bcaf941aef6aa85Jeff Sharkey */ 1871162fd77a8ff8467c96204c00bcaf941aef6aa85Jeff Sharkey public void setAutoStart(boolean autoStart) { 1881162fd77a8ff8467c96204c00bcaf941aef6aa85Jeff Sharkey mAutoStart = autoStart; 1891162fd77a8ff8467c96204c00bcaf941aef6aa85Jeff Sharkey } 1901162fd77a8ff8467c96204c00bcaf941aef6aa85Jeff Sharkey 1911162fd77a8ff8467c96204c00bcaf941aef6aa85Jeff Sharkey /** 1921162fd77a8ff8467c96204c00bcaf941aef6aa85Jeff Sharkey * Returns true if this view automatically calls {@link #startFlipping()} 1931162fd77a8ff8467c96204c00bcaf941aef6aa85Jeff Sharkey * when it becomes attached to a window. 1941162fd77a8ff8467c96204c00bcaf941aef6aa85Jeff Sharkey */ 1951162fd77a8ff8467c96204c00bcaf941aef6aa85Jeff Sharkey public boolean isAutoStart() { 1961162fd77a8ff8467c96204c00bcaf941aef6aa85Jeff Sharkey return mAutoStart; 1979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private final int FLIP_MSG = 1; 2009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private final Handler mHandler = new Handler() { 2029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 2039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void handleMessage(Message msg) { 2049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (msg.what == FLIP_MSG) { 2051162fd77a8ff8467c96204c00bcaf941aef6aa85Jeff Sharkey if (mRunning) { 2069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project showNext(); 2079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project msg = obtainMessage(FLIP_MSG); 2089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sendMessageDelayed(msg, mFlipInterval); 2099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project }; 2139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 214