[android] How to change shape color dynamically?

I have

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
   android:shape="rectangle">
    <solid
       android:color="#FFFF00" />
    <padding android:left="7dp"
        android:top="7dp"
        android:right="7dp"
        android:bottom="7dp" />
</shape>

<TextView
    android:background="@drawable/test"
    android:layout_height="45dp"
    android:layout_width="100dp"
    android:text="Moderate"
/>

So now I want this shape to change colors based on information I get back from a web service call. So it could be maybe yellow or green or red or whatever depending on the color I receive from the web serivce call.

How can I change the color of the shape? Based on this information?

This question is related to android android-layout xamarin.android shape

The answer is


drawable_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="@android:color/transparent" />

    <stroke
        android:width="1dp"
        android:color="#9f9f9f" />

    <corners
        android:bottomLeftRadius="5dp"
        android:bottomRightRadius="5dp"
        android:topLeftRadius="5dp"
        android:topRightRadius="5dp" />

</shape>

TextView

<androidx.appcompat.widget.AppCompatTextView
    android:id="@+id/textView"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:background="@drawable/drawable_rectangle"
    android:gravity="center"
    android:padding="10dp"
    android:text="Status"
    android:textColor="@android:color/white"
    android:textSize="20sp" />


public static void changeRectangleColor(View view, int color) {
    ((GradientDrawable) view.getBackground()).setStroke(1, color);
}    

changeRectangleColor(textView, ContextCompat.getColor(context, R.color.colorAccent));

You can build your own shapes in Java. I did this for an iPhone like Page Controler and paint the shapes in Java:

/**
 * Builds the active and inactive shapes / drawables for the page control
 */
private void makeShapes() {

    activeDrawable = new ShapeDrawable();
    inactiveDrawable = new ShapeDrawable();
    activeDrawable.setBounds(0, 0, (int) mIndicatorSize,
            (int) mIndicatorSize);
    inactiveDrawable.setBounds(0, 0, (int) mIndicatorSize,
            (int) mIndicatorSize);

    int i[] = new int[2];
    i[0] = android.R.attr.textColorSecondary;
    i[1] = android.R.attr.textColorSecondaryInverse;
    TypedArray a = this.getTheme().obtainStyledAttributes(i);

    Shape s1 = new OvalShape();
    s1.resize(mIndicatorSize, mIndicatorSize);
    Shape s2 = new OvalShape();
    s2.resize(mIndicatorSize, mIndicatorSize);

    ((ShapeDrawable) activeDrawable).getPaint().setColor(
            a.getColor(0, Color.DKGRAY));
    ((ShapeDrawable) inactiveDrawable).getPaint().setColor(
            a.getColor(1, Color.LTGRAY));

    ((ShapeDrawable) activeDrawable).setShape(s1);
    ((ShapeDrawable) inactiveDrawable).setShape(s2);
}

hope this helps. Greez Fabian


The simplest way to fill the shape with the Radius is:

XML:

<TextView
    android:id="@+id/textView"
    android:background="@drawable/test"
    android:layout_height="45dp"
    android:layout_width="100dp"
    android:text="Moderate"/>

Java:

(textView.getBackground()).setColorFilter(Color.parseColor("#FFDE03"), PorterDuff.Mode.SRC_IN);

This works for me, with an initial xml resource:

example.setBackgroundResource(R.drawable.myshape);
GradientDrawable gd = (GradientDrawable) example.getBackground().getCurrent();
gd.setColor(Color.parseColor("#000000"));
gd.setCornerRadii(new float[]{30, 30, 30, 30, 0, 0, 30, 30});
gd.setStroke(2, Color.parseColor("#00FFFF"), 5, 6);

Result of the above: http://i.stack.imgur.com/hKUR7.png


For me, it crashed because getBackground returned a GradientDrawable instead of a ShapeDrawable.

So i modified it like this:

((GradientDrawable)someView.getBackground()).setColor(someColor);

You can use a binding adapter(Kotlin) to achieve this. Create a binding adapter class named ChangeShapeColor like below

@BindingAdapter("shapeColor")

// Method to load shape and set its color 

fun loadShape(textView: TextView, color: String) {
// first get the drawable that you created for the shape 
val mDrawable = ContextCompat.getDrawable(textView.context, 
R.drawable.language_image_bg)
val  shape =   mDrawable as (GradientDrawable)
// use parse color method to parse #34444 to the int 
shape.setColor(Color.parseColor(color))
 }

Create a drawable shape in res/drawable folder. I have created a circle

<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="oval" >
<solid android:color="#anyColorCode"/>

<size
    android:width="@dimen/dp_16"
    android:height="@dimen/dp_16"/>
</shape>

Finally refer it to your view

  <TextView>
   .........
  app:shapeColor="@{modelName.colorString}"
 </Textview>

My shape xml :

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid  android:color="@android:color/transparent" />
<stroke android:width="0.5dp" android:color="@android:color/holo_green_dark"/>
</shape>

My activity xml :

<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
tools:context="cn.easydone.test.MainActivity">

<android.support.design.widget.AppBarLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:theme="@style/AppTheme.AppBarOverlay">

    <android.support.v7.widget.Toolbar
        android:id="@+id/toolbar"
        android:layout_width="match_parent"
        android:layout_height="?attr/actionBarSize"
        android:background="?attr/colorPrimary"
        app:popupTheme="@style/AppTheme.PopupOverlay" />
    <TextView
        android:id="@+id/test_text"
        android:background="@drawable/bg_stroke_dynamic_color"
        android:padding="20dp"
        android:text="asdasdasdasd"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"/>

</android.support.design.widget.AppBarLayout>

<android.support.v7.widget.RecyclerView
    android:id="@+id/recycler_view"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:padding="10dp"
    android:clipToPadding="false"
    app:layout_behavior="@string/appbar_scrolling_view_behavior" />

My activity java :

 TextView testText = (TextView) findViewById(R.id.test_text);
 ((GradientDrawable)testText.getBackground()).setStroke(10,Color.BLACK);

Result picture : result


I try Ronnie's answer, and my app crashed. Then I check my drawable xml. It looks like this:

<selector >...</selector>

. I changed it to this:(also changed attributes)

<shape> ... </shape>

It works.

For those who encounter the same problem.


    LayerDrawable bgDrawable = (LayerDrawable) button.getBackground();
    final GradientDrawable shape = (GradientDrawable)
            bgDrawable.findDrawableByLayerId(R.id.round_button_shape);
    shape.setColor(Color.BLACK);

If you have an imageView like this:

   <ImageView
    android:id="@+id/color_button"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_marginRight="10dp"
    android:src="@drawable/circle_color"/>

which give it a drawable shape as src, you can use this code to change shape's color:

ImageView iv = (ImageView)findViewById(R.id.color_button);
GradientDrawable bgShape = (GradientDrawable)iv.getDrawable();
bgShape.setColor(Color.BLACK);

Maybe someone else need to change color in the XML without create multiple drawables like I needed. Then make a circle drawable without color and then specify backgroundTint for the ImageView.

circle.xml

<?xml version="1.0" encoding="utf-8"?>
<shape
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="oval">
</shape>

And in your layout:

<ImageView
    android:layout_width="50dp"
    android:layout_height="50dp"
    android:background="@drawable/circle"
    android:backgroundTint="@color/red"/>

Edit:

There is a bug regarding this method that prevents it from working on Android Lollipop 5.0 (API level 21). But have been fixed in newer versions.


This solution worked for me using the android sdk v19:

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

circle.xml (drawable)

<?xml version="1.0" encoding="utf-8"?>
<shape
xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">

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

<size
    android:width="10dp"
    android:height="10dp"/>
</shape>

layout

<ImageView
      android:id="@+id/circleColor"
      android:layout_width="15dp"
       android:layout_height="15dp"
      android:textSize="12dp"
       android:layout_gravity="center"
       android:layout_marginLeft="10dp"
      android:background="@drawable/circle"/>

in activity

   circleColor = (ImageView) view.findViewById(R.id.circleColor);
   int color = Color.parseColor("#00FFFF");
   ((GradientDrawable)circleColor.getBackground()).setColor(color);

Examples related to android

Under what circumstances can I call findViewById with an Options Menu / Action Bar item? How to implement a simple scenario the OO way My eclipse won't open, i download the bundle pack it keeps saying error log getting " (1) no such column: _id10 " error java doesn't run if structure inside of onclick listener Cannot retrieve string(s) from preferences (settings) strange error in my Animation Drawable how to put image in a bundle and pass it to another activity FragmentActivity to Fragment A failure occurred while executing com.android.build.gradle.internal.tasks

Examples related to android-layout

How to check if a key exists in Json Object and get its value How to center the elements in ConstraintLayout Android - how to make a scrollable constraintlayout? Add ripple effect to my button with button background color? This view is not constrained vertically. At runtime it will jump to the left unless you add a vertical constraint Is it possible to put a ConstraintLayout inside a ScrollView? Differences between ConstraintLayout and RelativeLayout How to remove title bar from the android activity? How to have EditText with border in Android Lollipop Android: ScrollView vs NestedScrollView

Examples related to xamarin.android

Failure [INSTALL_FAILED_UPDATE_INCOMPATIBLE] even if app appears to not be installed appcompat-v7:21.0.0': No resource found that matches the given name: attr 'android:actionModeShareDrawable' How to change shape color dynamically?

Examples related to shape

what does numpy ndarray shape do? PySpark 2.0 The size or shape of a DataFrame Set android shape color programmatically How to change shape color dynamically?