How to change color of drawable shapes in android
Asked Answered
F

6

30

I am developing small android application in which I set drawable resource as background for linear layout. Now what I want to do change background color of linear layout dynamically, but within drawable resource. My code looks like :

//  bcd.xml
<selector xmlns:android="http://schemas.android.com/apk/res/android">

<item>        
    <shape>
        <gradient
            android:endColor="#22000000"
            android:startColor="#22000000"
            android:angle="270" />
        <stroke
            android:width="3dp"
            android:color="@color/white" />
        <corners
            android:radius="3dp" />
        <padding
            android:left="10dp"
            android:top="10dp"
            android:right="10dp"
            android:bottom="10dp" />
    </shape>
</item>

<LinearLayout 
android:id="@+id/lin_llt"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
>

and I set background for linear layout in my activity like this...

parentLayout = (LinearLayout) view.findViewById(R.id.lin_llt);
parentLayout.setBackgroundResource(R.drawable.bcd);

Now what I want to do i want to change color of my drawable resource that mean change color of my linear layout with rounded corner and padding define in drawable..

I tried this in following way

ShapeDrawable bgShape = (ShapeDrawable )parentLayout.getBackground();
bgShape.getPaint().setColor(Color.BLACK);

but its not working for me. any other solution .

So how to do it... Need help... thank you...

Factor answered 28/2, 2013 at 4:11 Comment(1)
Kotlin solution for whom may need : https://mcmap.net/q/93928/-how-to-programatically-change-the-startcolor-attribute-of-gradient-androidCorazoncorban
A
28

Change the layout color dynamically

LinearLayout Layout = (LinearLayout) findViewById(R.layout.id);
Layout.setBackgroundColor(Color.parseColor("#ffffff"));

Dynamically set the background color gradient

View layout = findViewById(R.id.mainlayout);

GradientDrawable gd = new GradientDrawable(
        GradientDrawable.Orientation.TOP_BOTTOM,
        new int[] {0xFF616261,0xFF131313});
gd.setCornerRadius(0f);

layout.setBackgroundDrawable(gd);
Antonio answered 28/2, 2013 at 4:23 Comment(4)
Hi priya thank you for reply. I can set background color in this way but after that i will not able to retain those rounded corners and padding which is define in drawable shape right? But I wanted to retain those as well.. is there any other solution...Factor
#6116215 -check this linkAntonio
Hi priya thank you for giving me exact solution. It works for my. And its working fine. can you just update your answer with that answer so that others can also use it.Factor
@Antonio Could you help with a similar problem in my question: #35399158Grade
L
12

You could try something like this :

Drawable sampleDrawable = context.getResources().getDrawable(R.drawable.balloons); 
sampleDrawable.setColorFilter(new PorterDuffColorFilter(0xffff00,PorterDuff.Mode.MULTIPLY));

and for more you could refer to :

How to change colors of a Drawable in Android?

Change drawable color programmatically

Android: Change Shape Color in runtime

http://pastebin.com/Hd2aU4XC

You could also try this :

private static final int[] FROM_COLOR = new int[]{49, 179, 110};
private static final int THRESHOLD = 3;

public void onCreate(Bundle savedInstanceState)
{
    super.onCreate(savedInstanceState);
    setContentView(R.layout.test_colors);

    ImageView iv = (ImageView) findViewById(R.id.img);
    Drawable d = getResources().getDrawable(RES);
    iv.setImageDrawable(adjust(d));
}

private Drawable adjust(Drawable d)
{
    int to = Color.RED;

    //Need to copy to ensure that the bitmap is mutable.
    Bitmap src = ((BitmapDrawable) d).getBitmap();
    Bitmap bitmap = src.copy(Bitmap.Config.ARGB_8888, true);
    for(int x = 0;x < bitmap.getWidth();x++)
        for(int y = 0;y < bitmap.getHeight();y++)
            if(match(bitmap.getPixel(x, y))) 
                bitmap.setPixel(x, y, to);

    return new BitmapDrawable(bitmap);
}

private boolean match(int pixel)
{
    //There may be a better way to match, but I wanted to do a comparison ignoring
    //transparency, so I couldn't just do a direct integer compare.
    return Math.abs(Color.red(pixel) - FROM_COLOR[0]) < THRESHOLD && Math.abs(Color.green(pixel) - FROM_COLOR[1]) < THRESHOLD && Math.abs(Color.blue(pixel) - FROM_COLOR[2]) < THRESHOLD;
}

as given in How to change colors of a Drawable in Android?

Lapland answered 28/2, 2013 at 4:15 Comment(4)
Hi lokoko thank you for reply. But when i tried your solution it gives me null pointer exception. What is wrong thing I am doing.Need helpFactor
Hi lokoko thank you for reply.. I am jus asking that above solution is for image drawable or it it also work for drawable shapes.. Coz it converting that drawable into bitmap.Factor
thank you lokoko for your help. i tried your first solution. i did some changes in my code. now its working without any error. Tha only problem is that it not applying the changed color. that mean it runs properly but not changing color of that drawable..Factor
I tried in this way Drawable sampleDrawable = context1.getResources().getDrawable(R.drawable.bcd); sampleDrawable.setColorFilter(new PorterDuffColorFilter(0xff0000,PorterDuff.Mode.MULTIPLY)); parentLayout.setBackgroundDrawable(sampleDrawable);Factor
P
3

The following works great for setting the color of the drawable programmatically without changing its shape:

parentLayout.getBackground().setColorFilter(
    Color.BLACK,
    PorterDuff.Mode.SRC_ATOP
);
Pfeffer answered 27/3, 2018 at 14:10 Comment(0)
D
2

use this..

<solid android:color="#e1e1e1" />

<stroke
    android:width="2dp"
    android:color="#808080" />

<corners android:radius="10dp" />

<padding
    android:bottom="5dp"
    android:left="5dp"
    android:right="5dp"
    android:top="5dp" />

Disburden answered 4/7, 2013 at 13:8 Comment(0)
B
2

Also possible way is to use:

val layerDrawable : LayerDrawable = imageView.background as LayerDrawable
val bgShape = layerDrawable.findDrawableByLayerId(R.id.shape_id) as GradientDrawable
bgShape.setColor(ContextCompat.getColor(context, R.color.colorPrimary))   

with example (drawable/circle.xml):

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:id="@+id/shape_id">
    <shape xmlns:android="http://schemas.android.com/apk/res/android"
        android:shape="rectangle">
        <corners android:radius="1000dp" />
        <solid android:color="#F4B528" />
        <padding
            android:bottom="4dp"
            android:left="4dp"
            android:right="4dp"
            android:top="4dp" />
    </shape>
</item>
</layer-list>

and ImageView:

<ImageView
    android:id="@+id/imageView"
    android:layout_width="16dp"
    android:layout_height="16dp"
    android:background="@drawable/circle" 
/>
Bryozoan answered 15/7, 2020 at 16:0 Comment(0)
C
1

One approach would be to create a second drawable XML with the 2nd color and then change the background of the layout with the 2nd drawable.

Command answered 28/2, 2013 at 4:16 Comment(3)
hi androidguy thank you for reply. I wanted to change color of that drawable dynamically. so dont want to create different layout xml files. Is there any other solutionFactor
Hi nilkash. Not that I'm aware of, but I'm looking forward to hearing other solutions.Command
@Command yours was the solution i was hoping to find as with the approaches in previous answers wont work for me as i am reusing the drawable at multiple places and the setbackgroundcolor() on an xml drawable is staticFocal

© 2022 - 2024 — McMap. All rights reserved.