diff --git a/core/api/current.txt b/core/api/current.txt index f5c67c1709316..1ed8fd53851a2 100644 --- a/core/api/current.txt +++ b/core/api/current.txt @@ -54625,6 +54625,8 @@ package android.widget { method public void setTextViewText(@IdRes int, CharSequence); method public void setTextViewTextSize(@IdRes int, int, float); method public void setUri(@IdRes int, String, android.net.Uri); + method public void setViewOutlinePreferredRadius(@IdRes int, float, int); + method public void setViewOutlinePreferredRadiusDimen(@IdRes int, @DimenRes int); method public void setViewPadding(@IdRes int, @Px int, @Px int, @Px int, @Px int); method public void setViewVisibility(@IdRes int, int); method public void showNext(@IdRes int); @@ -54649,6 +54651,12 @@ package android.widget { @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.RUNTIME) @java.lang.annotation.Target({java.lang.annotation.ElementType.TYPE}) public static @interface RemoteViews.RemoteView { } + public static final class RemoteViews.RemoteViewOutlineProvider extends android.view.ViewOutlineProvider { + ctor public RemoteViews.RemoteViewOutlineProvider(float); + method public void getOutline(@NonNull android.view.View, @NonNull android.graphics.Outline); + method public float getRadius(); + } + public abstract class RemoteViewsService extends android.app.Service { ctor public RemoteViewsService(); method public android.os.IBinder onBind(android.content.Intent); diff --git a/core/java/android/widget/RemoteViews.java b/core/java/android/widget/RemoteViews.java index dfef7ca825a13..6cb4b81827b98 100644 --- a/core/java/android/widget/RemoteViews.java +++ b/core/java/android/widget/RemoteViews.java @@ -47,6 +47,7 @@ import android.content.res.Configuration; import android.content.res.Resources; import android.content.res.TypedArray; import android.graphics.Bitmap; +import android.graphics.Outline; import android.graphics.PorterDuff; import android.graphics.Rect; import android.graphics.drawable.Drawable; @@ -79,6 +80,7 @@ import android.view.View; import android.view.ViewGroup; import android.view.ViewGroup.MarginLayoutParams; import android.view.ViewManager; +import android.view.ViewOutlineProvider; import android.view.ViewParent; import android.view.ViewStub; import android.widget.AdapterView.OnItemClickListener; @@ -194,6 +196,7 @@ public class RemoteViews implements Parcelable, Filter { private static final int COMPLEX_UNIT_DIMENSION_REFLECTION_ACTION_TAG = 25; private static final int SET_COMPOUND_BUTTON_CHECKED_TAG = 26; private static final int SET_RADIO_GROUP_CHECKED = 27; + private static final int SET_VIEW_OUTLINE_RADIUS_TAG = 28; /** @hide **/ @IntDef(prefix = "MARGIN_", value = { @@ -2642,6 +2645,88 @@ public class RemoteViews implements Parcelable, Filter { } } + private static class SetViewOutlinePreferredRadiusAction extends Action { + + private final boolean mIsDimen; + private final int mValue; + + SetViewOutlinePreferredRadiusAction(@IdRes int viewId, @DimenRes int dimenResId) { + this.viewId = viewId; + this.mIsDimen = true; + this.mValue = dimenResId; + } + + SetViewOutlinePreferredRadiusAction( + @IdRes int viewId, float radius, @ComplexDimensionUnit int units) { + this.viewId = viewId; + this.mIsDimen = false; + this.mValue = TypedValue.createComplexDimension(radius, units); + + } + + SetViewOutlinePreferredRadiusAction(Parcel in) { + viewId = in.readInt(); + mIsDimen = in.readBoolean(); + mValue = in.readInt(); + } + + @Override + public void writeToParcel(Parcel dest, int flags) { + dest.writeInt(viewId); + dest.writeBoolean(mIsDimen); + dest.writeInt(mValue); + } + + @Override + public void apply(View root, ViewGroup rootParent, OnClickHandler handler) + throws ActionException { + final View target = root.findViewById(viewId); + if (target == null) return; + + float radius; + if (mIsDimen) { + radius = mValue == 0 ? 0 : target.getResources().getDimension(mValue); + } else { + radius = TypedValue.complexToDimensionPixelSize(mValue, + target.getResources().getDisplayMetrics()); + } + target.setOutlineProvider(new RemoteViewOutlineProvider(radius)); + } + + @Override + public int getActionTag() { + return SET_VIEW_OUTLINE_RADIUS_TAG; + } + } + + /** + * OutlineProvider for a view with a radius set by + * {@link #setViewOutlinePreferredRadius(int, float, int)}. + */ + public static final class RemoteViewOutlineProvider extends ViewOutlineProvider { + + private final float mRadius; + + public RemoteViewOutlineProvider(float radius) { + mRadius = radius; + } + + /** Returns the corner radius used when providing the view outline. */ + public float getRadius() { + return mRadius; + } + + @Override + public void getOutline(@NonNull View view, @NonNull Outline outline) { + outline.setRoundRect( + 0 /*left*/, + 0 /* top */, + view.getWidth() /* right */, + view.getHeight() /* bottom */, + mRadius); + } + } + /** * Create a new RemoteViews object that will display the views contained * in the specified layout file. @@ -2860,6 +2945,8 @@ public class RemoteViews implements Parcelable, Filter { return new SetCompoundButtonCheckedAction(parcel); case SET_RADIO_GROUP_CHECKED: return new SetRadioGroupCheckedAction(parcel); + case SET_VIEW_OUTLINE_RADIUS_TAG: + return new SetViewOutlinePreferredRadiusAction(parcel); default: throw new ActionException("Tag " + tag + " not found"); } @@ -3594,6 +3681,28 @@ public class RemoteViews implements Parcelable, Filter { addAction(new LayoutParamAction(viewId, LayoutParamAction.LAYOUT_HEIGHT, heightDimen)); } + /** + * Sets an OutlineProvider on the view whose corner radius is a dimension calculated using + * {@link TypedValue#applyDimension(int, float, DisplayMetrics)}. This outline may change shape + * during system transitions. + * + *

NOTE: It is recommended to use {@link TypedValue#COMPLEX_UNIT_PX} only for 0. + * Setting margins in pixels will behave poorly when the RemoteViews object is used on a + * display with a different density. + */ + public void setViewOutlinePreferredRadius( + @IdRes int viewId, float radius, @ComplexDimensionUnit int units) { + addAction(new SetViewOutlinePreferredRadiusAction(viewId, radius, units)); + } + + /** + * Sets an OutlineProvider on the view whose corner radius is a dimension resource with + * {@code resId}. This outline may change shape during system transitions. + */ + public void setViewOutlinePreferredRadiusDimen(@IdRes int viewId, @DimenRes int resId) { + addAction(new SetViewOutlinePreferredRadiusAction(viewId, resId)); + } + /** * Call a method taking one boolean on a view in the layout for this RemoteViews. *