diff options
| author | Jeff Sharkey <jsharkey@android.com> | 2009-11-04 17:58:08 -0800 |
|---|---|---|
| committer | Jeff Sharkey <jsharkey@android.com> | 2009-11-16 14:27:19 -0800 |
| commit | 1162fd77a8ff8467c96204c00bcaf941aef6aa85 (patch) | |
| tree | 49aaf5420a1817823f70ac83ba238f22a2793236 /core/java/android/widget/ViewFlipper.java | |
| parent | ec8178eb0fb10e1ed753be4d065cf7f004355575 (diff) | |
Let RemoteViews nest children, allow ViewFlipper.
This change allows applications to nest children RemoteViews
inside an existing set of RemoteViews. These nested views
are inflated and treated as addView() calls.
This change also allows ViewFlipper through RemoteViews, and
adds logic surpress flipping when the parent window is
detached or behind the lockscreen. Also fixes ViewAnimator
to observe the measureAllChildren flag when set.
Fixes http://b/2239905
Diffstat (limited to 'core/java/android/widget/ViewFlipper.java')
| -rw-r--r-- | core/java/android/widget/ViewFlipper.java | 128 |
1 files changed, 113 insertions, 15 deletions
diff --git a/core/java/android/widget/ViewFlipper.java b/core/java/android/widget/ViewFlipper.java index 8a7946b951b1..aee25b029894 100644 --- a/core/java/android/widget/ViewFlipper.java +++ b/core/java/android/widget/ViewFlipper.java @@ -16,12 +16,15 @@ package android.widget; - +import android.content.BroadcastReceiver; import android.content.Context; +import android.content.Intent; +import android.content.IntentFilter; import android.content.res.TypedArray; import android.os.Handler; import android.os.Message; import android.util.AttributeSet; +import android.util.Log; import android.widget.RemoteViews.RemoteView; /** @@ -30,10 +33,22 @@ import android.widget.RemoteViews.RemoteView; * requested, can automatically flip between each child at a regular interval. * * @attr ref android.R.styleable#ViewFlipper_flipInterval + * @attr ref android.R.styleable#ViewFlipper_autoStart */ +@RemoteView public class ViewFlipper extends ViewAnimator { - private int mFlipInterval = 3000; - private boolean mKeepFlipping = false; + private static final String TAG = "ViewFlipper"; + private static final boolean LOGD = true; + + private static final int DEFAULT_INTERVAL = 3000; + + private int mFlipInterval = DEFAULT_INTERVAL; + private boolean mAutoStart = false; + + private boolean mRunning = false; + private boolean mStarted = false; + private boolean mVisible = false; + private boolean mUserPresent = true; public ViewFlipper(Context context) { super(context); @@ -44,14 +59,62 @@ public class ViewFlipper extends ViewAnimator { TypedArray a = context.obtainStyledAttributes(attrs, com.android.internal.R.styleable.ViewFlipper); - mFlipInterval = a.getInt(com.android.internal.R.styleable.ViewFlipper_flipInterval, - 3000); + mFlipInterval = a.getInt( + com.android.internal.R.styleable.ViewFlipper_flipInterval, DEFAULT_INTERVAL); + mAutoStart = a.getBoolean( + com.android.internal.R.styleable.ViewFlipper_autoStart, false); a.recycle(); } + private final BroadcastReceiver mReceiver = new BroadcastReceiver() { + @Override + public void onReceive(Context context, Intent intent) { + final String action = intent.getAction(); + if (Intent.ACTION_SCREEN_OFF.equals(action)) { + mUserPresent = false; + updateRunning(); + } else if (Intent.ACTION_USER_PRESENT.equals(action)) { + mUserPresent = true; + updateRunning(); + } + } + }; + + @Override + protected void onAttachedToWindow() { + super.onAttachedToWindow(); + + // Listen for broadcasts related to user-presence + final IntentFilter filter = new IntentFilter(); + filter.addAction(Intent.ACTION_SCREEN_OFF); + filter.addAction(Intent.ACTION_USER_PRESENT); + getContext().registerReceiver(mReceiver, filter); + + if (mAutoStart) { + // Automatically start when requested + startFlipping(); + } + } + + @Override + protected void onDetachedFromWindow() { + super.onDetachedFromWindow(); + mVisible = false; + + getContext().unregisterReceiver(mReceiver); + updateRunning(); + } + + @Override + protected void onWindowVisibilityChanged(int visibility) { + super.onWindowVisibilityChanged(visibility); + mVisible = visibility == VISIBLE; + updateRunning(); + } + /** * How long to wait before flipping to the next view - * + * * @param milliseconds * time in milliseconds */ @@ -64,26 +127,61 @@ public class ViewFlipper extends ViewAnimator { * Start a timer to cycle through child views */ public void startFlipping() { - if (!mKeepFlipping) { - mKeepFlipping = true; - showOnly(mWhichChild); - Message msg = mHandler.obtainMessage(FLIP_MSG); - mHandler.sendMessageDelayed(msg, mFlipInterval); - } + mStarted = true; + updateRunning(); } /** * No more flips */ public void stopFlipping() { - mKeepFlipping = false; + mStarted = false; + updateRunning(); + } + + /** + * Internal method to start or stop dispatching flip {@link Message} based + * on {@link #mRunning} and {@link #mVisible} state. + */ + private void updateRunning() { + boolean running = mVisible && mStarted && mUserPresent; + if (running != mRunning) { + if (running) { + showOnly(mWhichChild); + Message msg = mHandler.obtainMessage(FLIP_MSG); + mHandler.sendMessageDelayed(msg, mFlipInterval); + } else { + mHandler.removeMessages(FLIP_MSG); + } + mRunning = running; + } + if (LOGD) { + Log.d(TAG, "updateRunning() mVisible=" + mVisible + ", mStarted=" + mStarted + + ", mUserPresent=" + mUserPresent + ", mRunning=" + mRunning); + } } /** * Returns true if the child views are flipping. */ public boolean isFlipping() { - return mKeepFlipping; + return mStarted; + } + + /** + * Set if this view automatically calls {@link #startFlipping()} when it + * becomes attached to a window. + */ + public void setAutoStart(boolean autoStart) { + mAutoStart = autoStart; + } + + /** + * Returns true if this view automatically calls {@link #startFlipping()} + * when it becomes attached to a window. + */ + public boolean isAutoStart() { + return mAutoStart; } private final int FLIP_MSG = 1; @@ -92,7 +190,7 @@ public class ViewFlipper extends ViewAnimator { @Override public void handleMessage(Message msg) { if (msg.what == FLIP_MSG) { - if (mKeepFlipping) { + if (mRunning) { showNext(); msg = obtainMessage(FLIP_MSG); sendMessageDelayed(msg, mFlipInterval); |
