web-dev-qa-db-fra.com

Définir la couleur de forme Android par programme

Je suis en train d’éditer pour simplifier la question, en espérant que cela aide à obtenir une réponse précise.

Disons que j'ai la forme oval suivante:

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:Android="http://schemas.Android.com/apk/res/Android" Android:shape="oval">
    <solid Android:angle="270"
           Android:color="#FFFF0000"/>
    <stroke Android:width="3dp"
            Android:color="#FFAA0055"/>
</shape>

Comment définir la couleur par programmation, à partir d'une classe d'activité?

122
Cote Mounyo

Remarque: La réponse a été mise à jour pour couvrir le scénario dans lequel background est une instance de ColorDrawable. Merci Tyler Pfaff , pour avoir signalé ce point.

Le dessinable est un ovale et constitue l’arrière-plan d’un ImageView

Obtenez la Drawable à partir de imageView en utilisant getBackground():

Drawable background = imageView.getBackground();

Vérifiez contre les suspects habituels:

if (background instanceof ShapeDrawable) {
    // cast to 'ShapeDrawable'
    ShapeDrawable shapeDrawable = (ShapeDrawable) background;
    shapeDrawable.getPaint().setColor(ContextCompat.getColor(mContext,R.color.colorToSet));
} else if (background instanceof GradientDrawable) {
    // cast to 'GradientDrawable'
    GradientDrawable gradientDrawable = (GradientDrawable) background;
    gradientDrawable.setColor(ContextCompat.getColor(mContext,R.color.colorToSet));
} else if (background instanceof ColorDrawable) {
    // alpha value may need to be set again after this call
    ColorDrawable colorDrawable = (ColorDrawable) background;
    colorDrawable.setColor(ContextCompat.getColor(mContext,R.color.colorToSet));
}

Version compacte:

Drawable background = imageView.getBackground();
if (background instanceof ShapeDrawable) {
    ((ShapeDrawable)background).getPaint().setColor(ContextCompat.getColor(mContext,R.color.colorToSet));
} else if (background instanceof GradientDrawable) {
    ((GradientDrawable)background).setColor(ContextCompat.getColor(mContext,R.color.colorToSet));
} else if (background instanceof ColorDrawable) {
    ((ColorDrawable)background).setColor(ContextCompat.getColor(mContext,R.color.colorToSet));
}

Notez que la vérification nulle n'est pas requise.

Cependant, vous devriez utiliser mutate() sur les dessinables avant de les modifier s’ils sont utilisés ailleurs. (Par défaut, les objets dessinables chargés à partir de XML partagent le même état.)

207
Vikram

Fait comme ça:

    ImageView imgIcon = findViewById(R.id.imgIcon);
    GradientDrawable backgroundGradient = (GradientDrawable)imgIcon.getBackground();
    backgroundGradient.setColor(getResources().getColor(R.color.yellow));
40
Leonly91

Essaye ça:

 public void setGradientColors(int bottomColor, int topColor) {
 GradientDrawable gradient = new GradientDrawable(Orientation.BOTTOM_TOP, new int[]  
 {bottomColor, topColor});
 gradient.setShape(GradientDrawable.RECTANGLE);
 gradient.setCornerRadius(10.f);
 this.setBackgroundDrawable(gradient);
 }

pour plus de détails, consultez ce lien this

espérons l'aide.

13
androidqq6

espérons que cela aidera quelqu'un avec le même problème

GradientDrawable Gd = (GradientDrawable) YourImageView.getBackground();
//To shange the solid color
Gd.setColor(yourColor)

//To change the stroke color
int width_px = (int)TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, youStrokeWidth, getResources().getDisplayMetrics());
Gd.setStroke(width_px, yourColor);
11
medhdj

En développant la réponse de Vikram , si vous coloriez des vues dynamiques, comme des éléments de vue de recycleur, etc., vous voudrez probablement appeler mutate () avant de définir la couleur. Si vous ne le faites pas, toutes les vues ayant un dessin facile à dessiner (c'est-à-dire un arrière-plan) auront également leur dessin modifiable/coloré.

public static void setBackgroundColorAndRetainShape(final int color, final Drawable background) {

    if (background instanceof ShapeDrawable) {
        ((ShapeDrawable) background.mutate()).getPaint().setColor(color);
    } else if (background instanceof GradientDrawable) {
        ((GradientDrawable) background.mutate()).setColor(color);
    } else if (background instanceof ColorDrawable) {
        ((ColorDrawable) background.mutate()).setColor(color);
    }else{
        Log.w(TAG,"Not a valid background type");
    }

}
9
Tyler Pfaff

c'est la solution qui fonctionne pour moi ... l'a écrit dans une autre question: Comment changer la couleur de la forme de manière dynamique?

//get the image button by id
ImageButton myImg = (ImageButton) findViewById(R.id.some_id);

//get drawable from image button
GradientDrawable drawable = (GradientDrawable) myImg.getDrawable();

//set color as integer
//can use Color.parseColor(color) if color is a string
drawable.setColor(color)
6
Jay Paulynice

Cette question a reçu une réponse il y a quelque temps, mais elle peut être modernisée en réécrivant comme une fonction d'extension kotlin. 

fun Drawable.overrideColor(@ColorInt colorInt: Int) {
    when (this) {
        is GradientDrawable -> setColor(colorInt)
        is ShapeDrawable -> Paint.color = colorInt
        is ColorDrawable -> color = colorInt
    }
}
6
Carlos Paulino

Le moyen simple de remplir la forme avec le Radius est:

(view.getBackground()).setColorFilter(Color.parseColor("#FFDE03"), PorterDuff.Mode.SRC_IN);
0
SANAT

Rien ne fonctionne pour moi, mais quand je règle la teinte, cela fonctionne sur Shape Drawable

 Drawable background = imageView.getBackground();
 background.setTint(getRandomColor())

nécessite Android 5.0 API 21

0
Sumit