diff --git a/core/api/current.txt b/core/api/current.txt index 865772feed693..62a3c38e5738a 100644 --- a/core/api/current.txt +++ b/core/api/current.txt @@ -54517,19 +54517,26 @@ package android.widget { method public void setByte(@IdRes int, String, byte); method public void setChar(@IdRes int, String, char); method public void setCharSequence(@IdRes int, String, CharSequence); + method public void setCharSequence(@IdRes int, @NonNull String, @StringRes int); method public void setChronometer(@IdRes int, long, String, boolean); method public void setChronometerCountDown(@IdRes int, boolean); + method public void setColor(@IdRes int, @NonNull String, @ColorRes int); + method public void setColorStateList(@IdRes int, @NonNull String, @ColorRes int); method public void setContentDescription(@IdRes int, CharSequence); method public void setDisplayedChild(@IdRes int, int); method public void setDouble(@IdRes int, String, double); method public void setEmptyView(@IdRes int, @IdRes int); method public void setFloat(@IdRes int, String, float); + method public void setFloatDimen(@IdRes int, @NonNull String, @DimenRes int); + method public void setFloatDimen(@IdRes int, @NonNull String, float, int); method public void setIcon(@IdRes int, String, android.graphics.drawable.Icon); method public void setImageViewBitmap(@IdRes int, android.graphics.Bitmap); method public void setImageViewIcon(@IdRes int, android.graphics.drawable.Icon); method public void setImageViewResource(@IdRes int, @DrawableRes int); method public void setImageViewUri(@IdRes int, android.net.Uri); method public void setInt(@IdRes int, String, int); + method public void setIntDimen(@IdRes int, @NonNull String, @DimenRes int); + method public void setIntDimen(@IdRes int, @NonNull String, float, int); method public void setIntent(@IdRes int, String, android.content.Intent); method public void setLabelFor(@IdRes int, @IdRes int); method public void setLightBackgroundLayoutId(@LayoutRes int); diff --git a/core/java/android/widget/RemoteViews.java b/core/java/android/widget/RemoteViews.java index 8dafc5db61788..b47a0acc4fae9 100644 --- a/core/java/android/widget/RemoteViews.java +++ b/core/java/android/widget/RemoteViews.java @@ -17,6 +17,7 @@ package android.widget; import android.annotation.ColorInt; +import android.annotation.ColorRes; import android.annotation.DimenRes; import android.annotation.DrawableRes; import android.annotation.IdRes; @@ -25,6 +26,7 @@ import android.annotation.LayoutRes; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.Px; +import android.annotation.StringRes; import android.annotation.StyleRes; import android.app.Activity; import android.app.ActivityOptions; @@ -63,6 +65,7 @@ import android.os.StrictMode; import android.os.UserHandle; import android.text.TextUtils; import android.util.ArrayMap; +import android.util.DisplayMetrics; import android.util.IntArray; import android.util.Log; import android.util.Pair; @@ -180,6 +183,8 @@ public class RemoteViews implements Parcelable, Filter { private static final int SET_RIPPLE_DRAWABLE_COLOR_TAG = 21; private static final int SET_INT_TAG_TAG = 22; private static final int REMOVE_FROM_PARENT_ACTION_TAG = 23; + private static final int RESOURCE_REFLECTION_ACTION_TAG = 24; + private static final int COMPLEX_UNIT_DIMENSION_REFLECTION_ACTION_TAG = 25; /** @hide **/ @IntDef(prefix = "MARGIN_", value = { @@ -980,6 +985,45 @@ public class RemoteViews implements Parcelable, Filter { return rect; } + private static Class getParameterType(int type) { + switch (type) { + case BaseReflectionAction.BOOLEAN: + return boolean.class; + case BaseReflectionAction.BYTE: + return byte.class; + case BaseReflectionAction.SHORT: + return short.class; + case BaseReflectionAction.INT: + return int.class; + case BaseReflectionAction.LONG: + return long.class; + case BaseReflectionAction.FLOAT: + return float.class; + case BaseReflectionAction.DOUBLE: + return double.class; + case BaseReflectionAction.CHAR: + return char.class; + case BaseReflectionAction.STRING: + return String.class; + case BaseReflectionAction.CHAR_SEQUENCE: + return CharSequence.class; + case BaseReflectionAction.URI: + return Uri.class; + case BaseReflectionAction.BITMAP: + return Bitmap.class; + case BaseReflectionAction.BUNDLE: + return Bundle.class; + case BaseReflectionAction.INTENT: + return Intent.class; + case BaseReflectionAction.COLOR_STATE_LIST: + return ColorStateList.class; + case BaseReflectionAction.ICON: + return Icon.class; + default: + return null; + } + } + private MethodHandle getMethod(View view, String methodName, Class paramType, boolean async) { MethodArgs result; @@ -1282,7 +1326,8 @@ public class RemoteViews implements Parcelable, Filter { @Override public void apply(View root, ViewGroup rootParent, OnClickHandler handler) throws ActionException { - ReflectionAction ra = new ReflectionAction(viewId, methodName, ReflectionAction.BITMAP, + ReflectionAction ra = new ReflectionAction(viewId, methodName, + BaseReflectionAction.BITMAP, bitmap); ra.apply(root, rootParent, handler); } @@ -1301,7 +1346,7 @@ public class RemoteViews implements Parcelable, Filter { /** * Base class for the reflection actions. */ - private final class ReflectionAction extends Action { + private abstract class BaseReflectionAction extends Action { static final int BOOLEAN = 1; static final int BYTE = 2; static final int SHORT = 3; @@ -1324,17 +1369,14 @@ public class RemoteViews implements Parcelable, Filter { @UnsupportedAppUsage String methodName; int type; - @UnsupportedAppUsage - Object value; - ReflectionAction(@IdRes int viewId, String methodName, int type, Object value) { + BaseReflectionAction(@IdRes int viewId, String methodName, int type) { this.viewId = viewId; this.methodName = methodName; this.type = type; - this.value = value; } - ReflectionAction(Parcel in) { + BaseReflectionAction(Parcel in) { this.viewId = in.readInt(); this.methodName = in.readString8(); this.type = in.readInt(); @@ -1343,7 +1385,125 @@ public class RemoteViews implements Parcelable, Filter { Log.d(LOG_TAG, "read viewId=0x" + Integer.toHexString(this.viewId) + " methodName=" + this.methodName + " type=" + this.type); } + } + public void writeToParcel(Parcel out, int flags) { + out.writeInt(this.viewId); + out.writeString8(this.methodName); + out.writeInt(this.type); + } + + /** + * Returns the value to use as parameter for the method. + * + * The view might be passed as {@code null} if the parameter value is requested outside of + * inflation. If the parameter cannot be determined at that time, the method should return + * {@code null} but not raise any exception. + */ + @Nullable + protected abstract Object getParameterValue(@Nullable View view) throws ActionException; + + @Override + public final void apply(View root, ViewGroup rootParent, OnClickHandler handler) { + final View view = root.findViewById(viewId); + if (view == null) return; + + Class param = getParameterType(this.type); + if (param == null) { + throw new ActionException("bad type: " + this.type); + } + Object value = getParameterValue(view); + try { + getMethod(view, this.methodName, param, false /* async */).invoke(view, value); + } catch (Throwable ex) { + throw new ActionException(ex); + } + } + + @Override + public final Action initActionAsync(ViewTree root, ViewGroup rootParent, + OnClickHandler handler) { + final View view = root.findViewById(viewId); + if (view == null) return ACTION_NOOP; + + Class param = getParameterType(this.type); + if (param == null) { + throw new ActionException("bad type: " + this.type); + } + + Object value = getParameterValue(view); + try { + MethodHandle method = getMethod(view, this.methodName, param, true /* async */); + + if (method != null) { + Runnable endAction = (Runnable) method.invoke(view, value); + if (endAction == null) { + return ACTION_NOOP; + } + // Special case view stub + if (endAction instanceof ViewStub.ViewReplaceRunnable) { + root.createTree(); + // Replace child tree + root.findViewTreeById(viewId).replaceView( + ((ViewStub.ViewReplaceRunnable) endAction).view); + } + return new RunnableAction(endAction); + } + } catch (Throwable ex) { + throw new ActionException(ex); + } + + return this; + } + + public final int mergeBehavior() { + // smoothScrollBy is cumulative, everything else overwites. + if (methodName.equals("smoothScrollBy")) { + return MERGE_APPEND; + } else { + return MERGE_REPLACE; + } + } + + @Override + public final String getUniqueKey() { + // Each type of reflection action corresponds to a setter, so each should be seen as + // unique from the standpoint of merging. + return super.getUniqueKey() + this.methodName + this.type; + } + + @Override + public final boolean prefersAsyncApply() { + return this.type == URI || this.type == ICON; + } + + @Override + public final void visitUris(@NonNull Consumer visitor) { + switch (this.type) { + case URI: + final Uri uri = (Uri) getParameterValue(null); + if (uri != null) visitor.accept(uri); + break; + case ICON: + final Icon icon = (Icon) getParameterValue(null); + if (icon != null) visitIconUri(icon, visitor); + break; + } + } + } + + /** Class for the reflection actions. */ + private final class ReflectionAction extends BaseReflectionAction { + @UnsupportedAppUsage + Object value; + + ReflectionAction(@IdRes int viewId, String methodName, int type, Object value) { + super(viewId, methodName, type); + this.value = value; + } + + ReflectionAction(Parcel in) { + super(in); // For some values that may have been null, we first check a flag to see if they were // written to the parcel. switch (this.type) { @@ -1354,7 +1514,7 @@ public class RemoteViews implements Parcelable, Filter { this.value = in.readByte(); break; case SHORT: - this.value = (short)in.readInt(); + this.value = (short) in.readInt(); break; case INT: this.value = in.readInt(); @@ -1369,7 +1529,7 @@ public class RemoteViews implements Parcelable, Filter { this.value = in.readDouble(); break; case CHAR: - this.value = (char)in.readInt(); + this.value = (char) in.readInt(); break; case STRING: this.value = in.readString8(); @@ -1400,15 +1560,7 @@ public class RemoteViews implements Parcelable, Filter { } public void writeToParcel(Parcel out, int flags) { - out.writeInt(this.viewId); - out.writeString8(this.methodName); - out.writeInt(this.type); - //noinspection ConstantIfStatement - if (false) { - Log.d(LOG_TAG, "write viewId=0x" + Integer.toHexString(this.viewId) - + " methodName=" + this.methodName + " type=" + this.type); - } - + super.writeToParcel(out, flags); // For some values which are null, we record an integer flag to indicate whether // we have written a valid value to the parcel. switch (this.type) { @@ -1434,13 +1586,13 @@ public class RemoteViews implements Parcelable, Filter { out.writeDouble((Double) this.value); break; case CHAR: - out.writeInt((int)((Character)this.value).charValue()); + out.writeInt((int) ((Character) this.value).charValue()); break; case STRING: - out.writeString8((String)this.value); + out.writeString8((String) this.value); break; case CHAR_SEQUENCE: - TextUtils.writeToParcel((CharSequence)this.value, out, flags); + TextUtils.writeToParcel((CharSequence) this.value, out, flags); break; case BUNDLE: out.writeBundle((Bundle) this.value); @@ -1457,135 +1609,134 @@ public class RemoteViews implements Parcelable, Filter { } } - private Class getParameterType() { - switch (this.type) { - case BOOLEAN: - return boolean.class; - case BYTE: - return byte.class; - case SHORT: - return short.class; - case INT: - return int.class; - case LONG: - return long.class; - case FLOAT: - return float.class; - case DOUBLE: - return double.class; - case CHAR: - return char.class; - case STRING: - return String.class; - case CHAR_SEQUENCE: - return CharSequence.class; - case URI: - return Uri.class; - case BITMAP: - return Bitmap.class; - case BUNDLE: - return Bundle.class; - case INTENT: - return Intent.class; - case COLOR_STATE_LIST: - return ColorStateList.class; - case ICON: - return Icon.class; - default: - return null; - } - } - @Override - public void apply(View root, ViewGroup rootParent, OnClickHandler handler) { - final View view = root.findViewById(viewId); - if (view == null) return; - - Class param = getParameterType(); - if (param == null) { - throw new ActionException("bad type: " + this.type); - } - try { - getMethod(view, this.methodName, param, false /* async */).invoke(view, this.value); - } catch (Throwable ex) { - throw new ActionException(ex); - } - } - - @Override - public Action initActionAsync(ViewTree root, ViewGroup rootParent, OnClickHandler handler) { - final View view = root.findViewById(viewId); - if (view == null) return ACTION_NOOP; - - Class param = getParameterType(); - if (param == null) { - throw new ActionException("bad type: " + this.type); - } - - try { - MethodHandle method = getMethod(view, this.methodName, param, true /* async */); - - if (method != null) { - Runnable endAction = (Runnable) method.invoke(view, this.value); - if (endAction == null) { - return ACTION_NOOP; - } else { - // Special case view stub - if (endAction instanceof ViewStub.ViewReplaceRunnable) { - root.createTree(); - // Replace child tree - root.findViewTreeById(viewId).replaceView( - ((ViewStub.ViewReplaceRunnable) endAction).view); - } - return new RunnableAction(endAction); - } - } - } catch (Throwable ex) { - throw new ActionException(ex); - } - - return this; - } - - public int mergeBehavior() { - // smoothScrollBy is cumulative, everything else overwites. - if (methodName.equals("smoothScrollBy")) { - return MERGE_APPEND; - } else { - return MERGE_REPLACE; - } + protected Object getParameterValue(View view) throws ActionException { + return this.value; } @Override public int getActionTag() { return REFLECTION_ACTION_TAG; } + } - @Override - public String getUniqueKey() { - // Each type of reflection action corresponds to a setter, so each should be seen as - // unique from the standpoint of merging. - return super.getUniqueKey() + this.methodName + this.type; + private final class ResourceReflectionAction extends BaseReflectionAction { + + static final int DIMEN_RESOURCE = 1; + static final int COLOR_RESOURCE = 2; + static final int STRING_RESOURCE = 3; + + private final int mResourceType; + private final int mResId; + + ResourceReflectionAction(@IdRes int viewId, String methodName, int parameterType, + int resourceType, int resId) { + super(viewId, methodName, parameterType); + this.mResourceType = resourceType; + this.mResId = resId; + } + + ResourceReflectionAction(Parcel in) { + super(in); + this.mResourceType = in.readInt(); + this.mResId = in.readInt(); } @Override - public boolean prefersAsyncApply() { - return this.type == URI || this.type == ICON; + public void writeToParcel(Parcel dest, int flags) { + super.writeToParcel(dest, flags); + dest.writeInt(this.mResourceType); + dest.writeInt(this.mResId); } @Override - public void visitUris(@NonNull Consumer visitor) { - switch (this.type) { - case URI: - final Uri uri = (Uri) this.value; - visitor.accept(uri); - break; - case ICON: - final Icon icon = (Icon) this.value; - visitIconUri(icon, visitor); - break; + protected @NonNull Object getParameterValue(View view) throws ActionException { + Resources resources = view.getContext().getResources(); + try { + switch (this.mResourceType) { + case DIMEN_RESOURCE: + if (this.type == BaseReflectionAction.INT) { + return resources.getDimensionPixelSize(this.mResId); + } + return resources.getDimension(this.mResId); + case COLOR_RESOURCE: + switch(this.type) { + case BaseReflectionAction.INT: + return view.getContext().getColor(this.mResId); + case BaseReflectionAction.COLOR_STATE_LIST: + return view.getContext().getColorStateList(this.mResId); + default: + throw new ActionException( + "color resources must be used as int or ColorStateList, " + + "not " + this.type); + } + case STRING_RESOURCE: + return resources.getText(this.mResId); + default: + throw new ActionException("unknown resource type: " + this.mResourceType); + } + } catch (Throwable t) { + throw new ActionException(t); } } + + @Override + public int getActionTag() { + return RESOURCE_REFLECTION_ACTION_TAG; + } + } + + private final class ComplexUnitDimensionReflectionAction extends BaseReflectionAction { + + private final float mValue; + @ComplexDimensionUnit + private final int mUnit; + + ComplexUnitDimensionReflectionAction(int viewId, String methodName, int parameterType, + float value, @ComplexDimensionUnit int unit) { + super(viewId, methodName, parameterType); + this.mValue = value; + this.mUnit = unit; + } + + ComplexUnitDimensionReflectionAction(Parcel in) { + super(in); + this.mValue = in.readFloat(); + this.mUnit = in.readInt(); + } + + @Override + public void writeToParcel(Parcel dest, int flags) { + super.writeToParcel(dest, flags); + dest.writeFloat(this.mValue); + dest.writeInt(this.mUnit); + } + + @Override + protected Object getParameterValue(View view) throws ActionException { + DisplayMetrics dm = view.getContext().getResources().getDisplayMetrics(); + try { + int data = TypedValue.createComplexDimension(this.mValue, this.mUnit); + switch (this.type) { + case ReflectionAction.INT: + return TypedValue.complexToDimensionPixelSize(data, dm); + case ReflectionAction.FLOAT: + return TypedValue.complexToDimension(data, dm); + default: + throw new ActionException( + "parameter type must be INT or FLOAT, not " + this.type); + } + } catch (ActionException ex) { + throw ex; + } catch (Throwable t) { + throw new ActionException(t); + } + } + + @Override + public int getActionTag() { + return COMPLEX_UNIT_DIMENSION_REFLECTION_ACTION_TAG; + } } /** @@ -2611,6 +2762,10 @@ public class RemoteViews implements Parcelable, Filter { return new SetIntTagAction(parcel); case REMOVE_FROM_PARENT_ACTION_TAG: return new RemoveFromParentAction(parcel); + case RESOURCE_REFLECTION_ACTION_TAG: + return new ResourceReflectionAction(parcel); + case COMPLEX_UNIT_DIMENSION_REFLECTION_ACTION_TAG: + return new ComplexUnitDimensionReflectionAction(parcel); default: throw new ActionException("Tag " + tag + " not found"); } @@ -3113,7 +3268,7 @@ public class RemoteViews implements Parcelable, Filter { */ public void setProgressTintList(@IdRes int viewId, ColorStateList tint) { addAction(new ReflectionAction(viewId, "setProgressTintList", - ReflectionAction.COLOR_STATE_LIST, tint)); + BaseReflectionAction.COLOR_STATE_LIST, tint)); } /** @@ -3125,7 +3280,7 @@ public class RemoteViews implements Parcelable, Filter { */ public void setProgressBackgroundTintList(@IdRes int viewId, ColorStateList tint) { addAction(new ReflectionAction(viewId, "setProgressBackgroundTintList", - ReflectionAction.COLOR_STATE_LIST, tint)); + BaseReflectionAction.COLOR_STATE_LIST, tint)); } /** @@ -3137,7 +3292,7 @@ public class RemoteViews implements Parcelable, Filter { */ public void setProgressIndeterminateTintList(@IdRes int viewId, ColorStateList tint) { addAction(new ReflectionAction(viewId, "setIndeterminateTintList", - ReflectionAction.COLOR_STATE_LIST, tint)); + BaseReflectionAction.COLOR_STATE_LIST, tint)); } /** @@ -3159,8 +3314,8 @@ public class RemoteViews implements Parcelable, Filter { * @param colors the text colors to set */ public void setTextColor(@IdRes int viewId, ColorStateList colors) { - addAction(new ReflectionAction(viewId, "setTextColor", ReflectionAction.COLOR_STATE_LIST, - colors)); + addAction(new ReflectionAction(viewId, "setTextColor", + BaseReflectionAction.COLOR_STATE_LIST, colors)); } /** @@ -3353,7 +3508,7 @@ public class RemoteViews implements Parcelable, Filter { * @param value The value to pass to the method. */ public void setBoolean(@IdRes int viewId, String methodName, boolean value) { - addAction(new ReflectionAction(viewId, methodName, ReflectionAction.BOOLEAN, value)); + addAction(new ReflectionAction(viewId, methodName, BaseReflectionAction.BOOLEAN, value)); } /** @@ -3364,7 +3519,7 @@ public class RemoteViews implements Parcelable, Filter { * @param value The value to pass to the method. */ public void setByte(@IdRes int viewId, String methodName, byte value) { - addAction(new ReflectionAction(viewId, methodName, ReflectionAction.BYTE, value)); + addAction(new ReflectionAction(viewId, methodName, BaseReflectionAction.BYTE, value)); } /** @@ -3375,7 +3530,7 @@ public class RemoteViews implements Parcelable, Filter { * @param value The value to pass to the method. */ public void setShort(@IdRes int viewId, String methodName, short value) { - addAction(new ReflectionAction(viewId, methodName, ReflectionAction.SHORT, value)); + addAction(new ReflectionAction(viewId, methodName, BaseReflectionAction.SHORT, value)); } /** @@ -3386,9 +3541,58 @@ public class RemoteViews implements Parcelable, Filter { * @param value The value to pass to the method. */ public void setInt(@IdRes int viewId, String methodName, int value) { - addAction(new ReflectionAction(viewId, methodName, ReflectionAction.INT, value)); + addAction(new ReflectionAction(viewId, methodName, BaseReflectionAction.INT, value)); } + /** + * Call a method taking one int, a size in pixels, on a view in the layout for this + * RemoteViews. + * + * The dimension will be resolved from the resources at the time of inflation. + * + * @param viewId The id of the view on which to call the method. + * @param methodName The name of the method to call. + * @param dimenResource The resource to resolve and pass as argument to the method. + */ + public void setIntDimen(@IdRes int viewId, @NonNull String methodName, + @DimenRes int dimenResource) { + addAction(new ResourceReflectionAction(viewId, methodName, BaseReflectionAction.INT, + ResourceReflectionAction.DIMEN_RESOURCE, dimenResource)); + } + + /** + * Call a method taking one int, a size in pixels, on a view in the layout for this + * RemoteViews. + * + * The dimension will be resolved from the specified dimension at the time of inflation. + * + * @param viewId The id of the view on which to call the method. + * @param methodName The name of the method to call. + * @param value The value of the dimension. + * @param unit The unit in which the value is specified. + */ + public void setIntDimen(@IdRes int viewId, @NonNull String methodName, + float value, @ComplexDimensionUnit int unit) { + addAction(new ComplexUnitDimensionReflectionAction(viewId, methodName, ReflectionAction.INT, + value, unit)); + } + + /** + * Call a method taking one int, a color, on a view in the layout for this RemoteViews. + * + * The ColorStateList will be resolved from the resources at the time of inflation. + * + * @param viewId The id of the view on which to call the method. + * @param methodName The name of the method to call. + * @param colorResource The resource to resolve and pass as argument to the method. + */ + public void setColor(@IdRes int viewId, @NonNull String methodName, + @ColorRes int colorResource) { + addAction(new ResourceReflectionAction(viewId, methodName, BaseReflectionAction.INT, + ResourceReflectionAction.COLOR_RESOURCE, colorResource)); + } + + /** * Call a method taking one ColorStateList on a view in the layout for this RemoteViews. * @@ -3399,10 +3603,25 @@ public class RemoteViews implements Parcelable, Filter { * @hide */ public void setColorStateList(@IdRes int viewId, String methodName, ColorStateList value) { - addAction(new ReflectionAction(viewId, methodName, ReflectionAction.COLOR_STATE_LIST, + addAction(new ReflectionAction(viewId, methodName, BaseReflectionAction.COLOR_STATE_LIST, value)); } + /** + * Call a method taking one ColorStateList on a view in the layout for this RemoteViews. + * + * The ColorStateList will be resolved from the resources at the time of inflation. + * + * @param viewId The id of the view on which to call the method. + * @param methodName The name of the method to call. + * @param colorResource The resource to resolve and pass as argument to the method. + */ + public void setColorStateList(@IdRes int viewId, @NonNull String methodName, + @ColorRes int colorResource) { + addAction(new ResourceReflectionAction(viewId, methodName, + BaseReflectionAction.COLOR_STATE_LIST, ResourceReflectionAction.COLOR_RESOURCE, + colorResource)); + } /** * Call a method taking one long on a view in the layout for this RemoteViews. @@ -3412,7 +3631,7 @@ public class RemoteViews implements Parcelable, Filter { * @param value The value to pass to the method. */ public void setLong(@IdRes int viewId, String methodName, long value) { - addAction(new ReflectionAction(viewId, methodName, ReflectionAction.LONG, value)); + addAction(new ReflectionAction(viewId, methodName, BaseReflectionAction.LONG, value)); } /** @@ -3423,7 +3642,41 @@ public class RemoteViews implements Parcelable, Filter { * @param value The value to pass to the method. */ public void setFloat(@IdRes int viewId, String methodName, float value) { - addAction(new ReflectionAction(viewId, methodName, ReflectionAction.FLOAT, value)); + addAction(new ReflectionAction(viewId, methodName, BaseReflectionAction.FLOAT, value)); + } + + /** + * Call a method taking one float, a size in pixels, on a view in the layout for this + * RemoteViews. + * + * The dimension will be resolved from the resources at the time of inflation. + * + * @param viewId The id of the view on which to call the method. + * @param methodName The name of the method to call. + * @param dimenResource The resource to resolve and pass as argument to the method. + */ + public void setFloatDimen(@IdRes int viewId, @NonNull String methodName, + @DimenRes int dimenResource) { + addAction(new ResourceReflectionAction(viewId, methodName, BaseReflectionAction.FLOAT, + ResourceReflectionAction.DIMEN_RESOURCE, dimenResource)); + } + + /** + * Call a method taking one float, a size in pixels, on a view in the layout for this + * RemoteViews. + * + * The dimension will be resolved from the specified dimension at the time of inflation. + * + * @param viewId The id of the view on which to call the method. + * @param methodName The name of the method to call. + * @param value The value of the dimension. + * @param unit The unit in which the value is specified. + */ + public void setFloatDimen(@IdRes int viewId, @NonNull String methodName, + float value, @ComplexDimensionUnit int unit) { + addAction( + new ComplexUnitDimensionReflectionAction(viewId, methodName, ReflectionAction.FLOAT, + value, unit)); } /** @@ -3434,7 +3687,7 @@ public class RemoteViews implements Parcelable, Filter { * @param value The value to pass to the method. */ public void setDouble(@IdRes int viewId, String methodName, double value) { - addAction(new ReflectionAction(viewId, methodName, ReflectionAction.DOUBLE, value)); + addAction(new ReflectionAction(viewId, methodName, BaseReflectionAction.DOUBLE, value)); } /** @@ -3445,7 +3698,7 @@ public class RemoteViews implements Parcelable, Filter { * @param value The value to pass to the method. */ public void setChar(@IdRes int viewId, String methodName, char value) { - addAction(new ReflectionAction(viewId, methodName, ReflectionAction.CHAR, value)); + addAction(new ReflectionAction(viewId, methodName, BaseReflectionAction.CHAR, value)); } /** @@ -3456,7 +3709,7 @@ public class RemoteViews implements Parcelable, Filter { * @param value The value to pass to the method. */ public void setString(@IdRes int viewId, String methodName, String value) { - addAction(new ReflectionAction(viewId, methodName, ReflectionAction.STRING, value)); + addAction(new ReflectionAction(viewId, methodName, BaseReflectionAction.STRING, value)); } /** @@ -3467,7 +3720,24 @@ public class RemoteViews implements Parcelable, Filter { * @param value The value to pass to the method. */ public void setCharSequence(@IdRes int viewId, String methodName, CharSequence value) { - addAction(new ReflectionAction(viewId, methodName, ReflectionAction.CHAR_SEQUENCE, value)); + addAction(new ReflectionAction(viewId, methodName, BaseReflectionAction.CHAR_SEQUENCE, + value)); + } + + /** + * Call a method taking one CharSequence on a view in the layout for this RemoteViews. + * + * The CharSequence will be resolved from the resources at the time of inflation. + * + * @param viewId The id of the view on which to call the method. + * @param methodName The name of the method to call. + * @param stringResource The resource to resolve and pass as argument to the method. + */ + public void setCharSequence(@IdRes int viewId, @NonNull String methodName, + @StringRes int stringResource) { + addAction( + new ResourceReflectionAction(viewId, methodName, BaseReflectionAction.CHAR_SEQUENCE, + ResourceReflectionAction.STRING_RESOURCE, stringResource)); } /** @@ -3485,7 +3755,7 @@ public class RemoteViews implements Parcelable, Filter { value.checkFileUriExposed("RemoteViews.setUri()"); } } - addAction(new ReflectionAction(viewId, methodName, ReflectionAction.URI, value)); + addAction(new ReflectionAction(viewId, methodName, BaseReflectionAction.URI, value)); } /** @@ -3510,7 +3780,7 @@ public class RemoteViews implements Parcelable, Filter { * @param value The value to pass to the method. */ public void setBundle(@IdRes int viewId, String methodName, Bundle value) { - addAction(new ReflectionAction(viewId, methodName, ReflectionAction.BUNDLE, value)); + addAction(new ReflectionAction(viewId, methodName, BaseReflectionAction.BUNDLE, value)); } /** @@ -3521,7 +3791,7 @@ public class RemoteViews implements Parcelable, Filter { * @param value The {@link android.content.Intent} to pass the method. */ public void setIntent(@IdRes int viewId, String methodName, Intent value) { - addAction(new ReflectionAction(viewId, methodName, ReflectionAction.INTENT, value)); + addAction(new ReflectionAction(viewId, methodName, BaseReflectionAction.INTENT, value)); } /** @@ -3532,7 +3802,7 @@ public class RemoteViews implements Parcelable, Filter { * @param value The {@link android.graphics.drawable.Icon} to pass the method. */ public void setIcon(@IdRes int viewId, String methodName, Icon value) { - addAction(new ReflectionAction(viewId, methodName, ReflectionAction.ICON, value)); + addAction(new ReflectionAction(viewId, methodName, BaseReflectionAction.ICON, value)); } /**