web-dev-qa-db-ja.com

画面サイズのパーセンテージとしてのグラデーション半径

私は放射状グラデーションの背景で描画可能な図形を作成しようとしています。半径は画面サイズに調整されます(関連する documentation を見てください)。

これは私のコードです:

<?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」を削除すると機能しますが、半径は静的であるため、画面サイズに調整されません...何か問題はありますか?

34
shaylh

私がテストしたものから、%は機能しますが、期待どおりではありません。
まず第一に

Android:gradientRadius="50"

ピクセル50pxとして値をとるようです

Android:gradientRadius="50%"

50%= 0.5ピクセルのように変換されます。

Android:gradientRadius="5000%"

半径50pxが表示されます。
使用%pも同様の結果になります。明らかにこれはあまり役に立たないため、将来的に変更されることを期待しています。通常、XML ShapeDrawableリソースは、サイズを外部コンテナーに適合させます。この場合、gradientRadiusはコンテナーに関係なくサイズを設定します。

12
ilomambo

最終的に、次のオーバーライドされた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によるカスタマイズを許可するパーセンテージ。

8
marnaish

GradientRadiusのパーセンテージは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を作成することはできないため、ビューの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>
5
miguel

ドローアブルxmlでは、パーセンテージで表される形状の角の半径を設定することはできません。

0
Adobels

この投稿と同様に、実行時に描画可能な形状を作成できます https://stackoverflow.com/a/4943888/604504

このようにして、画面サイズを取得した後にパーセンテージを計算できます。

0
Josh