2012-06-24 46 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> 

但它好好嘗試似乎工作。如果我刪除了「%p」,它可以工作,但是半徑將是靜態的,因此不會調整到屏幕大小......任何想法有什麼不對?

+0

gradientRadius是一個基於整數值的屬性。將百分比或任何類型的測量值都不起作用。我知道這不是你正在尋找的答案,但至少它有助於縮小你所尋找的範圍。 – Sababado

+0

這裏同樣的問題(至少在Eclipse中預覽我的佈局時):如果使用'%'或'%p'指定半徑,則不應用漸變 –

+0

最糟糕的部分是,即使我有整數資源定義在別處,並在這裏引用(@ integer/gradientRadius)。它似乎只接受絕對的硬編碼整數。 – Gunanaresh

回答

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" 


首先似乎取值爲像素50像素

android:gradientRadius="50%" 

轉換彷彿50%= 0.5像素,嘗試

android:gradientRadius="5000%" 

,你會看到一個50px半徑。
使用%p有類似的結果。顯然這是我希望將來會改變的,因爲它沒有太多用處。通常XML ShapeDrawable資源會將其大小調整爲某個外部容器,在這種情況下,無論容器如何,gradientRadius都會設置大小。

+7

「50000%p」與「50」相同,就像ilomambo之前所說的那樣如果你想要一些可讀性,你不應該使用它。 – Joan

+3

更好的解決方案是使用values-mdpi,values-hdpi文件夾並提供不同的維度值並在半徑值字段中引用它們。 –

5

請注意gradientRadius百分比在棒棒糖中起作用。但是如果你必須支持pre-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>