34

我正在尝试创建一个具有径向渐变背景的可绘制形状,其半径将适应屏幕尺寸(查看相关文档)。

这是我的代码:

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="rectangle" >

    <gradient
        android:endColor="#000"
        android:gradientRadius="50%p"
        android:startColor="#5d2456"
        android:type="radial" />
</shape>

但它似乎不起作用。如果我删除“%p”,它会起作用,但是半径将是静态的,因此不会调整到屏幕尺寸......知道有什么问题吗?

4

5 回答 5

12

根据我的测试,%确实有效,但不像您预期​​的那样。
首先

android:gradientRadius="50"

似乎将值作为像素 50px

android:gradientRadius="50%"

转换为好像 50% = 0.5 px,试试

android:gradientRadius="5000%"

你会看到一个 50px 的半径。
使用%p有类似的结果。显然这是我希望将来会改变的东西,因为它并没有太大的用处。通常 XML ShapeDrawable 资源会调整它们的大小以适应某些外部容器,在这种情况下gradientRadius,无论容器如何设置大小。

于 2013-07-25T15:03:59.873 回答
9

我最终使用以下覆盖的 onDraw 方法创建了一个自定义视图:

@Override
protected void onDraw(Canvas canvas) {
    Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);

    int maxSize = Math.max(getHeight(), getWidth());
    RadialGradient gradient = new RadialGradient(
            getWidth()/2,
            getHeight()/2,
            maxSize, 
            new int[] {Color.RED, Color.BLACK},
            new float[] {0, 1}, 
            android.graphics.Shader.TileMode.CLAMP);

    paint.setDither(true);
    paint.setShader(gradient);

    canvas.drawRect(0, 0, getWidth(), getHeight(), paint);
}

在您的布局中只需添加视图:

<yourpackage.GradientView
    android:layout_width="match_parent"
    android:layout_height="match_parent" />

当然,可以为视图创建属性,例如。颜色、百分比以允许通过 XML 进行自定义。

于 2013-07-06T14:52:15.617 回答
5

请注意,梯度半径百分比在 Lollipop 中确实有效。但是,如果您必须支持棒棒糖之前的版本,我扩展了@marnaish 的答案,添加了 XML 属性。我的 gradientRadius 被定义为父视图宽度的百分比:

public class RadialGradientView extends View {
    private final int endColor;
    private final int startColor;
    private final float gradientRadiusWidthPercent;
    private final float centerY;
    private final float centerX;
    private Paint paint;

    public RadialGradientView(Context context, AttributeSet attrs) {
        super(context, attrs);

        TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.RadialGradientView, 0, 0);

        startColor = a.getColor(R.styleable.RadialGradientView_startColor, Color.RED);
        endColor = a.getColor(R.styleable.RadialGradientView_endColor, Color.BLACK);
        gradientRadiusWidthPercent = a.getFloat(R.styleable.RadialGradientView_gradientRadiusWidthPercent, 1);
        centerX = a.getFloat(R.styleable.RadialGradientView_centerX, .5f);
        centerY = a.getFloat(R.styleable.RadialGradientView_centerY, .5f);

        a.recycle();
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        int parentWidth = MeasureSpec.getSize(widthMeasureSpec);
        int parentHeight = MeasureSpec.getSize(heightMeasureSpec);

        paint = new Paint(Paint.ANTI_ALIAS_FLAG);
        RadialGradient gradient = new RadialGradient(
                parentWidth*centerX,
                parentHeight*centerY,
                parentWidth*gradientRadiusWidthPercent,
                new int[] {startColor, endColor},
                null,
                android.graphics.Shader.TileMode.CLAMP);

        paint.setDither(true);
        paint.setShader(gradient);

    }

    @Override
    protected void onDraw(Canvas canvas) {
        canvas.drawRect(0, 0, getWidth(), getHeight(), paint);
    }

}

在 attrs.xml 中:

<declare-styleable name="RadialGradientView">
    <attr name="startColor" format="color|reference"/>
    <attr name="endColor" format="color|reference"/>
    <attr name="gradientRadiusWidthPercent" format="float"/>
    <attr name="centerX" format="float"/>
    <attr name="centerY" format="float"/>
</declare-styleable>

不幸的是,您无法从自定义类创建 XML 可绘制对象,因此您无法将其设置为 View 的 android:background。解决方法是使用 FrameLayout 将其分层作为背景。

<FrameLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="100dp">

    <com.RadialGradientView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:centerX=".3"
        app:centerY=".5"
        app:endColor="#0f0"
        app:startColor="#f00"
        app:gradientRadiusWidthPercent=".5"
        />
    <TextView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:gravity="center"
        android:text="What's up world?"/>
</FrameLayout>
于 2015-03-03T01:06:24.583 回答
0

您可以在运行时创建一个可绘制的形状,类似于这篇文章https://stackoverflow.com/a/4943888/604504

这样,您可以在检索屏幕尺寸后计算百分比。

于 2012-09-12T02:43:29.497 回答
0

在可绘制的 xml 中设置以百分比表示的形状角半径是不可能的。

于 2019-03-01T16:10:41.300 回答