私は放射状グラデーションの背景で描画可能な図形を作成しようとしています。半径は画面サイズに調整されます(関連する 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」を削除すると機能しますが、半径は静的であるため、画面サイズに調整されません...何か問題はありますか?
私がテストしたものから、%
は機能しますが、期待どおりではありません。
まず第一に
Android:gradientRadius="50"
ピクセル50pxとして値をとるようです
Android:gradientRadius="50%"
50%= 0.5ピクセルのように変換されます。
Android:gradientRadius="5000%"
半径50pxが表示されます。
使用%p
も同様の結果になります。明らかにこれはあまり役に立たないため、将来的に変更されることを期待しています。通常、XML ShapeDrawableリソースは、サイズを外部コンテナーに適合させます。この場合、gradientRadius
はコンテナーに関係なくサイズを設定します。
最終的に、次のオーバーライドされた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によるカスタマイズを許可するパーセンテージ。
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>
ドローアブルxmlでは、パーセンテージで表される形状の角の半径を設定することはできません。
この投稿と同様に、実行時に描画可能な形状を作成できます https://stackoverflow.com/a/4943888/604504
このようにして、画面サイズを取得した後にパーセンテージを計算できます。