Programmatically change colors in drawable xml file - android

I need to change my application's colors during runtime. I parse data file to get colors and I save it in class with static fields and methods:
public class Colors {
private static String colorOneBackground = "#00577F";
private static String colorOneForeground = "#FFFFFF";
public static void setColorOneBackground(String colorOneBackground) {
Colors.colorOneBackground = colorOneBackground;
}
public static int getColorOneForeground() {
return Color.parseColor(colorOneForeground);
}
// more colors...
Then, for example when I want to change the background of screen I do it so:
RelativeLayout relativeLayout = (RelativeLayout) myView.findViewById(R.id.loginBackground);
relativeLayout.setBackgroundColor(Colors.getColorOneBackground());
Same with textviews and other widgets. However, I have encountered one problem. Some styles are defined in Drawable folder, for example,
mybutton.xml:
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android=" http://schemas.android.com/apk/res/android "
android:shape="rectangle">
<gradient
android:startColor="#FFFFFF"
android:centerColor="#FFFFFF"
android:endColor="#FFFFFF"
android:angle="270" />
<corners android:radius="5dp" />
<stroke android:width="3px" android:color="#000000" />
</shape>
And I set this as my button's background:
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/title"
android:background="#drawable/mybutton" />
As I said I want to change these color values programatically. So I want to know if it is possible to dinamically change color values defined in xml file?

try this : to change color in your drawable xml file:
button.setBackgroundResource(R.drawable.mybutton); //drawable id
GradientDrawable gd = (GradientDrawable) button.getBackground().getCurrent();
gd.setColor(Color.parseColor("#000000")); //set color
gd.setStroke(2, Color.parseColor("#00FFFF"), 5, 6);

Related

Android Drawable color runtime

I am developing an android app. I have two different text view with different text view as shown in below two images:
Text view one:
Text view Two:
I have a question, should I create two different drawable files with different colors or should I create a single drawable file and change the color runtime?
What's the standard way to achieve this?
If I should create a single drawable file then how should I change to color programmatically?
try this simple example
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
TextView tvWelcome = findViewById(R.id.tv_welcome);
TextView tvHello = findViewById(R.id.tv_hello);
recolor(this, tvWelcome, getResources().getColor(R.color.red));
recolor(this, tvHello, getResources().getColor(R.color.green));
}
private void recolor(Context context, TextView textView, #ColorInt int color) {
Drawable unwrappedDrawable = AppCompatResources.getDrawable(context, R.drawable.item_background);
if (unwrappedDrawable != null) {
DrawableCompat.wrap(unwrappedDrawable);
DrawableCompat.setTint(unwrappedDrawable, color);
textView.setBackground(unwrappedDrawable);
}
}
}
item_background.xml
<?xml version="1.0" encoding="UTF-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="#ffffffff" />
<corners
android:bottomLeftRadius="7dp"
android:bottomRightRadius="7dp"
android:topLeftRadius="7dp"
android:topRightRadius="7dp" />
</shape>

Background Colour Change At Run Time Android

I am Using LinearLayout to set BackGround Shape which has curve Corner. I have created drawable XML file. When I try to change LinearLayout backGround Colour at RunTime In My Activity, the colour appears is reflected in the Layout but background shape is not been applied. Need help on this
My layout.xml file:
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/month_card"
android:backgroundTint="#drawable/circle_corner_rectangle"
app:backgroundTintMode="src_over">
shape.xml file
<shape android:shape="rectangle" >
<corners android:radius="500dip" />
<stroke android:width="2dip" android:color="#color/colorPrimary" />
<gradient android:angle="-90"/>
</shape>
Finally setting it on runtime inside the activity
layout.setBackgroundColor(colorList.get(position));
Use
final int sdk = android.os.Build.VERSION.SDK_INT;
if(sdk < android.os.Build.VERSION_CODES.JELLY_BEAN) {
layout.setBackgroundDrawable(ContextCompat.getDrawable(context, R.drawable.circle_corner_rectangle)
);
} else {
layout.setBackground(ContextCompat.getDrawable(context,R.drawable.circle_corner_rectangle));
}
instead of
layout.setBackgroundColor(colorList.get(position));
Try this code
circle_corner_rectangle.xml
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle" >
<solid android:color="#E0F2F1" />
<corners android:radius="6dp"/>
</shape>
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/month_card"
android:backgroundTint="#drawable/circle_corner_rectangle">
Maybe this work in your case
val shape = GradientDrawable()
shape.shape = GradientDrawable.RECTANGLE
shape.setStroke(mStrokeWidth!!,mStrokeColor!!)
shape.cornerRadius = 2f
imageView.background = shape
This code is in kotlin
Just try this ,,
layout.setBackgroundColor(Color.parseColor("#20A4E8"));
(or)
layout.setBackgroundColor(Color.BLUE);
just add another xml file You want and add this code in run time
layout.setBackgroundTintList(getContext.getResources().getColorStateList(R.color.your_xml_name));
Try this:
Drawable drawable = yourView.getBackground();
try {
drawable.setColorFilter(Color.parseColor(yourColor), PorterDuff.Mode.MULTIPLY);
} catch (Exception e) {
e.printStackTrace();
}

java.lang.ClassCastException: android.graphics.drawable.LayerDrawable cannot be cast to android.graphics.drawable.GradientDrawable

In my application I am trying change background color for each listView item. And for that I am using shapes which in layer-list.
Here is my code
drop_shadow.xml
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item>
<shape android:shape="rectangle">
<gradient android:startColor="#B7B7B7"
android:endColor="#A1A1A1"
android:angle="270"/>
<corners android:radius="10dp" />
</shape>
</item>
<item android:top="1px">
<shape android:shape="rectangle">
<solid android:color="#color/color11"/>
<corners android:radius="10dp" />
</shape>
</item>
</layer-list>
main.xml
<RelativeLayout
android:orientation="vertical"
android:id="#+id/mainLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#drawable/drop_shadow"/>
When I call this method I have ClassCastException
private void setRoundedBackground(View view,int color){
GradientDrawable gradientDrawable;
gradientDrawable = (GradientDrawable) view.getBackground().mutate();
gradientDrawable.setColor(getResources().getColor(color));
gradientDrawable.invalidateSelf();
}
How could I get GradientDrawable from LayerDrawable?
you can create gradient drawable dynamically.. use below class
import android.graphics.drawable.GradientDrawable;
public class SomeDrawable extends GradientDrawable {
public SomeDrawable(int pStartColor, int pCenterColor, int pEndColor, int pStrokeWidth, int pStrokeColor, float cornerRadius) {
super(Orientation.BOTTOM_TOP,new int[]{pStartColor,pCenterColor,pEndColor});
setStroke(pStrokeWidth,pStrokeColor);
setShape(GradientDrawable.RECTANGLE);
setCornerRadius(cornerRadius);
}
}
and use this class as below
SomeDrawable drawable = new SomeDrawable(Color.parseColor("Start Color Code"),Color.parseColor("Center Color Code"),Color.parseColor("End Color Code"),1,Color.BLACK,00);
yourLayout.setBackgroundDrawable(drawable);
They are both a subclass of Drawable, so you can't cast them to each other, only to their parent classes.
i guess it's better to use separacte colors.xml file for the color of the shape, and use tag, you can delete the .
after all your shape both is the same which is rectangle.
previously i got the same error because i'm using and inside the same xml.

Get a textView background color with ShapeDrawable

I have a textview with the background defined in a xml file.
<TextView
android:id="#+id/event_tvColor"
android:layout_width="40dip"
android:layout_height="40dip"
android:text=" "
android:background="#drawable/et_style_color_service_edit"
android:clickable="true"
/>
xml file : et_style_color_service_edit.xml
<?xml version="1.0" encoding="UTF-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="oval">
<solid android:color="#color/eventColor"/>
<stroke android:width="0sp" android:color="#FFFFFF" />
<size android:width="20dp"
android:height="20dp"/>
</shape>
And i need to get the color that the view have in a one time.
ShapeDrawable sc = (ShapeDrawable)tvColor.getBackground();
...............
Note that i need to use ShapeDrawable and not GradientDrawable.
Thank you for your help and time.
Solution........
Solution The xml loads into the app as a gradientdrawable and not as a shapedrawable. We have to define the shapeDrawable in java
ShapeDrawable sd = new ShapeDrawable(new RectShape);
sd.getPaint().setColor(0xFF0000FF);
if anyone have a better solution can tell.
After further research, there currently is no way of getting the xml loaded ShapeDrawable's color. What you have to do is just track your color changes so you know what color you are setting it to, ie:
int currentColor = Color.WHITE; //this is the default color (color set in xml)
public void changeColor() {
if (currentColor == Color.WHITE) {
currentColor = Color.BLUE;
} else {
currentColor = Color.WHITE;
}
GradientDrawable gd = (GradientDrawable)tvColor.getBackground();
gd.setColor(currentColor);
}

How to change color of drawable shapes in android

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...
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);
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?
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
);
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" />
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"
/>
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.

Categories

Resources