Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android - Set drawable's gradient dynamically

Tags:

java

android

I have a drawable from an XML resource, and I want to use that drawable but set the gradient color dynamically. So far I have something like this:

<?xml version="1.0" encoding="utf-8"?>
<shape
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="rectangle">
    <corners
        android:radius="3dip">
    </corners>
    <gradient
        android:angle="90"
        android:type="linear"
        android:startColor="#FFFFFFFF"
        android:centerColor="#FFFF0000"
        android:endColor="#FFFF0000">
    </gradient>
</shape>

Now I figured that I would be able to make the colors dynamically by getting the drawable at runtime, casting it as a GradientDrawable, and using a method to set the colors. The GradientDrawable however does not have such a method, and one can only set the colors in the constructor. I find it very strange that this is the case because all the other aspects of the gradient are settable. Is there an easier way than overriding onDraw() and doing the gradient myself? Some of the classes I'm trying to use are very poorly documented..

like image 698
Samuel Avatar asked Mar 08 '11 14:03

Samuel


2 Answers

Resources are primarily static, and typically do not allow modification. Some resource types allow you to "clone" a mutable copy. GradientDrawable only allows you to set the colors in the contstuctor (as you discovered), so you need to create those internally if you want to control the colors dynamically at runtime, or better yet, select one of a fixed number of backgrounds from resource instead. As mentioned previously, use setBackgroundDrawable() to install your background at runtime. No need to pass judgment, just Get-R-Done!

like image 199
escape-llc Avatar answered Oct 18 '22 18:10

escape-llc


Make a GradientDrawable Class like this:

public class RoundedDrawable extends GradientDrawable {

        public RoundedDrawable(int shape, int solidColor, int strokeWidth,
     int strokeColor, float[] fourRadii) {

            this.mutate();
            this.setShape(shape);
            this.setColor(solidColor);
            this.setStroke(strokeWidth, strokeColor);
            this.setCornerRadii(fourRadii);
        }
    }

Now use this in your Activity like this:

public class AAActivity extends Activity {

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.fragment_transaction_layout);

    RoundedDrawable customBg;

    RelativeLayout relList = (RelativeLayout) findViewById(R.id.relList);
    float radii[]={5.0f, 5.0f, 5.0f, 5.0f, 5.0f, 5.0f, 5.0f, 5.0f};
    customBg = new RoundedDrawable(GradientDrawable.RECTANGLE,Color.parseColor("#FFFFFF"),
            2, Color.parseColor("#8C8C8C"),radii);
    relList.setBackgroundDrawable(customBg);

    LinearLayout linearItemsRow = (LinearLayout) findViewById(R.id.linearItemsRow);
    float[] rowRadii={5.0f, 5.0f, 5.0f, 5.0f, 0.0f, 0.0f, 0.0f, 0.0f};
    customBg = new RoundedDrawable(GradientDrawable.RECTANGLE,Color.parseColor("#CBCBCB"),
            0, 0, rowRadii);
    linearItemsRow.setBackgroundDrawable(customBg);


}

}

Hope this will help.

like image 35
Enthu_Learner Avatar answered Oct 18 '22 18:10

Enthu_Learner