web-dev-qa-db-fra.com

Android - comment définir ShapeDrawables par programme?

Ce que j'essaie de réaliser, c'est d'utiliser un Drawable avec quelques couches à l'intérieur, mais de contrôler certaines valeurs lors de l'exécution, telles que startColor pour le dégradé. Voici ce que j'ai dans my_layered_shape.xml:

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

Et si j'utilise mMyImageView.setBackgroundResource (R.drawable.my_layered_shape) cela fonctionne. Cela ne me dérange pas de diviser le xml si je le dois, ou de faire le tout par programmation tant qu'il existe un moyen d'obtenir les différentes valeurs de couleur. Le concept que je privilégie par programmation (c'est-à-dire mon meilleur coup à faire la même chose dans le code que ce xml) est:

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

Merci.

27
Carl Whalley

Il semble que cela ne fonctionne pas avec ShapeDrawable, mais jetez un œil à mon GradientDrawable exemple:

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

Vous pouvez également avoir besoin de la méthode suivante:

Gd.setGradientCenter(float x, float y);
Gd.setGradientRadius(float gradientRadius);
25
marnaish

Je vais juste laisser ça ici ... Pas encore testé

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

Edit: testé Maintenant, j'ai eu une erreur. Vous devez en fait décrire chaque état. Si vous groupez des états, ils ne seront déclenchés que si tous arrivent à la fois ...

5
BooNonMooN