2012-06-24 12 views
35

Estoy tratando de crear una forma dibujable con fondo de degradado radial, con un radio que se ajustará al tamaño de la pantalla (consulte el correspondiente documentation).Radio de degradado como porcentaje del tamaño de pantalla

Este es mi código:

<?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> 

Pero doens't parece funcionar. si elimino el "% p", funciona, pero luego el radio será estático, por lo tanto, no se ajustará al tamaño de la pantalla ... ¿Alguna idea de lo que está mal?

+0

gradientRadius es una propiedad que se basa en un valor entero. Poner un porcentaje o cualquier tipo de valor de medición no funcionará. Sé que esta no es la respuesta que está buscando, pero al menos ayudará a reducir lo que está buscando. – Sababado

+0

Mismo problema aquí (al menos al previsualizar mi diseño en Eclipse): el degradado no se aplica si el radio se especifica con '%' o '% p' –

+0

La peor parte es que no funciona incluso si tengo un recurso entero definido en otro lugar, y refiérelo aquí (@ integer/gradientRadius). Parece aceptar solo enteros enteros codificados absolutos. – Gunanaresh

Respuesta

8

terminé creando una vista personalizada con el siguiente overriden onDraw método:

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

En su diseño sólo tiene que añadir la vista:

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

Por supuesto que sería posible crear atributos para el Ver, ej. color, porcentaje para permitir la personalización a través de XML.

11

Por lo que he probado, el % funciona, pero no como esperaba.
En primer lugar

android:gradientRadius="50" 

parece tomar el valor como píxeles 50px

android:gradientRadius="50%" 

se convierte como si el 50% = 0,5 px, tratar

android:gradientRadius="5000%" 

y verá una Radio 50px.
El uso de %p tiene un resultado similar. Obviamente, esto es algo que espero se modifique en el futuro, ya que no tiene mucho uso. Por lo general, los recursos de XML ShapeDrawable adaptan su tamaño a algún contenedor externo; en este caso, gradientRadius establece el tamaño independientemente del contenedor.

+7

"50000% p" es lo mismo que "50", como ilomambo dijo antes, por lo que si quieres algo de legibilidad no deberías usarlo. – Joan

+3

Una mejor solución será usar las carpetas values-mdpi, values-hdpi y proporcionar diferentes valores de dimensión y hacer referencia a ellos en el campo de valor del radio. –

5

Tenga en cuenta que los porcentajes de gradienteRadius funcionan en Lollipop. Pero si tiene que admitir pre-Lollipop, amplié la respuesta de @ marnaish agregando atributos XML. Mi gradientRadius se define como un porcentaje del ancho de la vista padre:

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

} 

En 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> 

Lamentablemente no se puede crear una dibujable XML a partir de una clase personalizada, por lo que se puede' t configúralo como un android de View: fondo. La solución consiste en utilizar FrameLayout para superponerlo como fondo.

<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> 
Cuestiones relacionadas