Définir la couleur de forme android programmatically

Je édite pour rendre la question plus simple, en espérant que cela aide à une réponse précise.

dis que j'ai la forme suivante oval :

<?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 programmer la couleur, à partir d'une classe d'activité?

114
demandé sur Sky Kelsey 2013-07-24 04:52:18

8 réponses

Note : la réponse a été mise à jour pour couvrir le scénario où background est une instance de ColorDrawable . Merci Tyler Pfaff , d'avoir souligné ceci.

le drawable est un ovale et est le fond D'une ImageView

Get Drawable à partir de imageView à l'aide getBackground() :

Drawable background = imageView.getBackground();

contre-Vérifier 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 devez utiliser mutate() sur les tiroirs avant de les modifier s'ils sont utilisés ailleurs. (Par défaut, les drawables chargés à partir de XML partagent le même état.)

197
répondu Vikram 2017-05-23 11:47:19

faites comme ceci:

    ImageView imgIcon = findViewById(R.id.imgIcon);
    GradientDrawable backgroundGradient = (GradientDrawable)imgIcon.getBackground();
    backgroundGradient.setColor(getResources().getColor(R.color.yellow));
39
répondu Leonly91 2014-05-19 14:03:40

essayez ceci:

 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 ce

l'espoir de l'aide.

12
répondu androidqq6 2013-07-24 01:05:00

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

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
répondu medhdj 2014-09-05 15:17:37

extension sur Vikram's réponse, si vous coloriez des vues dynamiques, comme des articles de vue recycler, etc.... Alors, vous voulez probablement appel muter() avant de définir la couleur. Si vous ne le faites pas, toutes les vues qui ont un dessin commun (I. e a background) aura également leur dessin modifié/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");
    }

}
8
répondu Tyler Pfaff 2017-05-23 11:47:19

c'est la solution qui fonctionne pour moi...il a écrit dans une autre question ainsi: Comment changer dynamiquement la couleur de la forme?

//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
répondu Jay Paulynice 2017-05-23 10:31:12

cette question a été répondue il y a un certain temps, mais il peut se moderniser en réécrivant comme une fonction d'extension de kotlin.

fun Drawable.overrideColor(@ColorInt colorInt: Int) {
    when (this) {
        is GradientDrawable -> setColor(colorInt)
        is ShapeDrawable -> paint.color = colorInt
        is ColorDrawable -> color = colorInt
    }
}
4
répondu Carlos Paulino 2017-10-09 22:30:51

une solution plus simple aujourd'hui serait d'utiliser votre forme comme un fond et puis changer sa couleur programmatiquement via

view.getBackground().setColorFilter(Color.parseColor("#343434"), PorterDuff.Mode.SRC_OVER)

4
répondu George 2018-07-02 11:57:36