Add a RemoteViews API for outline corner radii

Bug: 179478275
Test: built test app to use APIs, atest
Change-Id: I0da0f3fcb5d01f9e94e75f2fc17494bb7902ac7f
This commit is contained in:
Stevie Kideckel
2021-02-05 13:37:32 +00:00
parent a0735849df
commit 2d2d20741b
2 changed files with 117 additions and 0 deletions

View File

@@ -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);

View File

@@ -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.
*
* <p>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.
*