am 06dc03f2: Let RemoteViews nest children, allow ViewFlipper.
Merge commit '06dc03f2cf98862717ba1aa0e858897363abc369' into eclair-mr2-plus-aosp * commit '06dc03f2cf98862717ba1aa0e858897363abc369': Let RemoteViews nest children, allow ViewFlipper.
This commit is contained in:
@@ -1967,6 +1967,17 @@
|
||||
visibility="public"
|
||||
>
|
||||
</field>
|
||||
<field name="autoStart"
|
||||
type="int"
|
||||
transient="false"
|
||||
volatile="false"
|
||||
value="16843446"
|
||||
static="true"
|
||||
final="true"
|
||||
deprecated="not deprecated"
|
||||
visibility="public"
|
||||
>
|
||||
</field>
|
||||
<field name="autoText"
|
||||
type="int"
|
||||
transient="false"
|
||||
@@ -190341,6 +190352,21 @@
|
||||
<parameter name="parcel" type="android.os.Parcel">
|
||||
</parameter>
|
||||
</constructor>
|
||||
<method name="addView"
|
||||
return="void"
|
||||
abstract="false"
|
||||
native="false"
|
||||
synchronized="false"
|
||||
static="false"
|
||||
final="false"
|
||||
deprecated="not deprecated"
|
||||
visibility="public"
|
||||
>
|
||||
<parameter name="viewId" type="int">
|
||||
</parameter>
|
||||
<parameter name="nestedView" type="android.widget.RemoteViews">
|
||||
</parameter>
|
||||
</method>
|
||||
<method name="apply"
|
||||
return="android.view.View"
|
||||
abstract="false"
|
||||
@@ -190417,6 +190443,19 @@
|
||||
<parameter name="v" type="android.view.View">
|
||||
</parameter>
|
||||
</method>
|
||||
<method name="removeAllViews"
|
||||
return="void"
|
||||
abstract="false"
|
||||
native="false"
|
||||
synchronized="false"
|
||||
static="false"
|
||||
final="false"
|
||||
deprecated="not deprecated"
|
||||
visibility="public"
|
||||
>
|
||||
<parameter name="viewId" type="int">
|
||||
</parameter>
|
||||
</method>
|
||||
<method name="setBitmap"
|
||||
return="void"
|
||||
abstract="false"
|
||||
@@ -197002,6 +197041,17 @@
|
||||
<parameter name="attrs" type="android.util.AttributeSet">
|
||||
</parameter>
|
||||
</constructor>
|
||||
<method name="isAutoStart"
|
||||
return="boolean"
|
||||
abstract="false"
|
||||
native="false"
|
||||
synchronized="false"
|
||||
static="false"
|
||||
final="false"
|
||||
deprecated="not deprecated"
|
||||
visibility="public"
|
||||
>
|
||||
</method>
|
||||
<method name="isFlipping"
|
||||
return="boolean"
|
||||
abstract="false"
|
||||
@@ -197013,6 +197063,19 @@
|
||||
visibility="public"
|
||||
>
|
||||
</method>
|
||||
<method name="setAutoStart"
|
||||
return="void"
|
||||
abstract="false"
|
||||
native="false"
|
||||
synchronized="false"
|
||||
static="false"
|
||||
final="false"
|
||||
deprecated="not deprecated"
|
||||
visibility="public"
|
||||
>
|
||||
<parameter name="autoStart" type="boolean">
|
||||
</parameter>
|
||||
</method>
|
||||
<method name="setFlipInterval"
|
||||
return="void"
|
||||
abstract="false"
|
||||
|
||||
@@ -457,6 +457,46 @@ public class RemoteViews implements Parcelable, Filter {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Equivalent to calling {@link ViewGroup#addView(View)} after inflating the
|
||||
* given {@link RemoteViews}, or calling {@link ViewGroup#removeAllViews()}
|
||||
* when null. This allows users to build "nested" {@link RemoteViews}.
|
||||
*/
|
||||
private class ViewGroupAction extends Action {
|
||||
public ViewGroupAction(int viewId, RemoteViews nestedViews) {
|
||||
this.viewId = viewId;
|
||||
this.nestedViews = nestedViews;
|
||||
}
|
||||
|
||||
public ViewGroupAction(Parcel parcel) {
|
||||
viewId = parcel.readInt();
|
||||
nestedViews = parcel.readParcelable(null);
|
||||
}
|
||||
|
||||
public void writeToParcel(Parcel dest, int flags) {
|
||||
dest.writeInt(TAG);
|
||||
dest.writeInt(viewId);
|
||||
dest.writeParcelable(nestedViews, 0 /* no flags */);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void apply(View root) {
|
||||
final Context context = root.getContext();
|
||||
final ViewGroup target = (ViewGroup) root.findViewById(viewId);
|
||||
if (nestedViews != null) {
|
||||
// Inflate nested views and add as children
|
||||
target.addView(nestedViews.apply(context, target));
|
||||
} else if (target != null) {
|
||||
// Clear all children when nested views omitted
|
||||
target.removeAllViews();
|
||||
}
|
||||
}
|
||||
|
||||
int viewId;
|
||||
RemoteViews nestedViews;
|
||||
|
||||
public final static int TAG = 4;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new RemoteViews object that will display the views contained
|
||||
@@ -493,6 +533,9 @@ public class RemoteViews implements Parcelable, Filter {
|
||||
case ReflectionAction.TAG:
|
||||
mActions.add(new ReflectionAction(parcel));
|
||||
break;
|
||||
case ViewGroupAction.TAG:
|
||||
mActions.add(new ViewGroupAction(parcel));
|
||||
break;
|
||||
default:
|
||||
throw new ActionException("Tag " + tag + " not found");
|
||||
}
|
||||
@@ -519,7 +562,31 @@ public class RemoteViews implements Parcelable, Filter {
|
||||
}
|
||||
mActions.add(a);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Equivalent to calling {@link ViewGroup#addView(View)} after inflating the
|
||||
* given {@link RemoteViews}. This allows users to build "nested"
|
||||
* {@link RemoteViews}. In cases where consumers of {@link RemoteViews} may
|
||||
* recycle layouts, use {@link #removeAllViews(int)} to clear any existing
|
||||
* children.
|
||||
*
|
||||
* @param viewId The id of the parent {@link ViewGroup} to add child into.
|
||||
* @param nestedView {@link RemoteViews} that describes the child.
|
||||
*/
|
||||
public void addView(int viewId, RemoteViews nestedView) {
|
||||
addAction(new ViewGroupAction(viewId, nestedView));
|
||||
}
|
||||
|
||||
/**
|
||||
* Equivalent to calling {@link ViewGroup#removeAllViews()}.
|
||||
*
|
||||
* @param viewId The id of the parent {@link ViewGroup} to remove all
|
||||
* children from.
|
||||
*/
|
||||
public void removeAllViews(int viewId) {
|
||||
addAction(new ViewGroupAction(viewId, null));
|
||||
}
|
||||
|
||||
/**
|
||||
* Equivalent to calling View.setVisibility
|
||||
*
|
||||
|
||||
@@ -16,8 +16,10 @@
|
||||
|
||||
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;
|
||||
@@ -30,10 +32,19 @@ 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 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 +55,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 +123,57 @@ 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;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 +182,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);
|
||||
|
||||
@@ -2138,6 +2138,8 @@
|
||||
</declare-styleable>
|
||||
<declare-styleable name="ViewFlipper">
|
||||
<attr name="flipInterval" format="integer" min="0" />
|
||||
<!-- When true, automatically start animating -->
|
||||
<attr name="autoStart" format="boolean" />
|
||||
</declare-styleable>
|
||||
<declare-styleable name="ViewSwitcher">
|
||||
</declare-styleable>
|
||||
|
||||
@@ -1201,8 +1201,8 @@
|
||||
<public type="attr" name="quickContactBadgeStyleSmallWindowSmall" />
|
||||
<public type="attr" name="quickContactBadgeStyleSmallWindowMedium" />
|
||||
<public type="attr" name="quickContactBadgeStyleSmallWindowLarge" />
|
||||
|
||||
<public type="attr" name="wallpaperAuthor" />
|
||||
<public type="attr" name="wallpaperDescription" />
|
||||
<public type="attr" name="autoStart" />
|
||||
|
||||
</resources>
|
||||
|
||||
Reference in New Issue
Block a user