2011-08-22 21 views
27

Lo que estoy tratando de lograr es utilizar un Drawable con un par de capas dentro de él, pero controlar algunos valores en tiempo de ejecución como el startColor para el degradado. Esto es lo que tengo en my_layered_shape.xml:Android: ¿cómo definir ShapeDrawables programmatically?

<?xml version="1.0" encoding="utf-8"?> 
<layer-list xmlns:android="http://schemas.android.com/apk/res/android" > 
    <item> 
    <shape android:shape="rectangle"> 
     <stroke android:width="1dp" android:color="#FF000000" /> 
     <solid android:color="#FFFFFFFF" /> 
    </shape> 
    </item> 
    <item android:top="1dp" android:bottom="1dp"> 
    <shape android:shape="rectangle"> 
    <stroke android:width="1dp" android:color="#FF000000" /> 
    <gradient 
     android:startColor="#FFFFFFFF" 
     android:centerColor="#FFFFFF88" 
     android:endColor="#FFFFFFFF" 
     android:gradientRadius="250" 
     android:centerX="1" 
     android:centerY="0" 
     android:angle="315" 
    />    
    </shape> 
    </item> 
</layer-list> 

Y si uso mMyImageView.setBackgroundResource (R.drawable.my_layered_shape) funciona. No me importa dividir el xml si tengo que hacerlo, o hacer todo el trabajo programáticamente siempre que haya una manera de obtener los distintos valores de color. El concepto voy por programación (es decir, mi mejor oportunidad de hacer lo mismo en código como este XML) es:

Drawable[] layers = new Drawable[2]; 

ShapeDrawable sd1 = new ShapeDrawable(new RectShape()); 
sd1.getPaint().setColor(0xFFFFFFFF); 
sd1.getPaint().setStyle(Style.STROKE); 
sd1.getPaint().setStrokeWidth(1); 
// sd1.getPaint().somehow_set_stroke_color? 

ShapeDrawable sd2 = new ShapeDrawable(new RectShape()); 
sd2.getPaint().setColor(0xFF000000); 
sd2.getPaint().setStyle(Style.STROKE); 
// sd2.getPaint().somehow_set_stroke_color? 
// sd2.getPaint().somehow_set_gradient_params? 

layers[0] = sd1; 
layers[1] = sd2; 
LayerDrawable composite = new LayerDrawable(layers); 
mMyImageView.setBackgroundDrawable(composite); 

Gracias.

Respuesta

25

Parece que es no funciona con ShapeDrawable, pero echa un vistazo a mi GradientDrawable ejemplo:

GradientDrawable gd = new GradientDrawable(Orientation.BOTTOM_TOP, new int[]{Color.RED, Color.GREEN}); 
gd.setStroke(10, Color.BLUE); 

También puede ser necesario siguiente método:

gd.setGradientCenter(float x, float y); 
gd.setGradientRadius(float gradientRadius); 
+7

curiosamente, la clase GradientDrawable no tiene el método 'setPadding', ¿hay algún problema? – Palani

+0

Excelente, resolvió mi problema – Goofy

5

Sólo va dejar esto aquí ... No probado aún

/** 
* Created by Nedo on 09.04.2015. 
*/ 
public class ShapeBuilder { 

    public static Drawable generateSelectorFromDrawables(Drawable pressed, Drawable normal) { 
     StateListDrawable states = new StateListDrawable(); 
     states.addState(new int[]{ -android.R.attr.state_focused, -android.R.attr.state_pressed, -android.R.attr.state_selected}, normal); 
     states.addState(new int[]{ android.R.attr.state_pressed}, pressed); 
     states.addState(new int[]{ android.R.attr.state_focused}, pressed); 
     states.addState(new int[]{ android.R.attr.state_selected}, pressed); 

     return states; 
    } 

    public static Drawable generateShape(String colorTop, String colorBot, String colorStroke, int stokeSize, float strokeRadius) { 
     int top, bot, stroke; 
     top = Color.parseColor(colorTop); 
     bot = Color.parseColor(colorBot); 
     stroke = Color.parseColor(colorStroke); 

     GradientDrawable drawable = new GradientDrawable(GradientDrawable.Orientation.BOTTOM_TOP, new int[]{top, bot}); 
     drawable.setStroke(stokeSize, stroke); 
     drawable.setCornerRadius(strokeRadius); 

     return drawable; 
    } 

    public static Drawable buildSelectorShapeFromColors(String colorNormalStroke, String colorNormalBackTop, String colorNormalBackBot, 
                 String colorPressedStroke, String colorPressedBackTop, String colorPressedBackBot, 
                 int strokeSize, float strokeRadius) { 

     Drawable pressed = generateShape(colorPressedBackTop, colorPressedBackBot, colorPressedStroke, strokeSize, strokeRadius); 
     Drawable normal = generateShape(colorNormalBackTop, colorNormalBackBot, colorNormalStroke, strokeSize, strokeRadius); 
     return generateSelectorFromDrawables(pressed, normal); 
    } 
} 

Edición: probado Ahora, tenía un error. Realmente tiene que describir cada estado individual. Si agrupa estados, solo se activarán si todos ellos actúan a la vez ...

Cuestiones relacionadas