2012-06-24 10 views
35

私は、画面サイズに合わせて半径を持つ放射状の勾配の背景を持つ形状ドロアブルを作成しようとしています(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> 

しかし、それは動作するようですdoens't。 "%p"を削除すると動作しますが、半径は静的なので、画面サイズには調整されません...何が間違っているのでしょうか?

+0

gradientRadiusは、整数値に基づいたプロパティです。パーセント値またはあらゆる種類の測定値を入力しても機能しません。私はこれがあなたが探している答えではないことを知っていますが、少なくともあなたが探しているものを絞り込むのに役立ちます。 – Sababado

+0

同じ問題があります(少なくとも私のレイアウトをEclipseでプレビューするとき):半径が '%'または '%p'で指定されている場合、グラジェントは適用されません –

+0

最悪の部分は、整数リソースは他の場所で定義され、ここでは(@ integer/gradientRadius)参照してください。絶対にハードコードされた整数だけを受け入れるようです。 – Gunanaresh

答えて

0

あなたはこの記事にランタイム似時には、画面サイズを取得した後、パーセンテージを計算できhttps://stackoverflow.com/a/4943888/604504

この方法は形状描画可能を作成することができます。

8

私は次の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によるカスタマイズが可能です。

11

私がテストしたところから、%は動作しますが、期待どおりに動作しません。
すべて

android:gradientRadius="50" 

の最初のピクセルは50px

android:gradientRadius="50%" 

として値を取るように見えるが、50%= 0.5ピクセルかのように変換さ

android:gradientRadius="5000%" 

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

+7

「50000%p」は「50」と同じです。読みやすさが必要な場合は、使用しないでください。 – Joan

+3

より良い解決策は、values-mdpi、values-hdpiフォルダを使用し、異なる値を提供し、半径値フィールドでそれらを参照することです。 –

5

LollipopではgradientRadiusの割合が有効です。しかし、あなたがLollipopより前にサポートする必要があるなら、私は@ marnaishの答えをXML属性を追加して展開しました。私gradientRadiusは、親ビューの幅の割合として定義されます。attrs.xmlで

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

} 

<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の描画可能を作成することはできませんので、あなたは「できますビューのアンドロイド:背景として設定します。この問題を回避するには、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> 
関連する問題