Changing gradient background colors on Android at runtime

I'm experimenting with Drawable backgrounds and have had no problems so far.

I'm now trying to change the gradient background color at runtime.

Unfortunately, there's no API to change it at runtime, it seems. Not even by trying to mutate() the drawable, as explained here: Drawable mutations

The sample XML looks like this. It works, as expected.

<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="rectangle">
    <gradient
        android:startColor="#330000FF"
        android:endColor="#110000FF"
        android:angle="90"/>
</shape>

Sadly, I want a list with various colors, and they'd have to be programatically altered at runtime.

Is there another way to create this gradient background at runtime? Perhaps even not using XML altogether?


Solution 1:

Yes! Found a way!

Had to forget about XML, but here's how I did it:

On my getView() overloaded function (ListAdapter) I just had to:

    int h = v.getHeight();
    ShapeDrawable mDrawable = new ShapeDrawable(new RectShape());
    mDrawable.getPaint().setShader(new LinearGradient(0, 0, 0, h, Color.parseColor("#330000FF"), Color.parseColor("#110000FF"), Shader.TileMode.REPEAT));
    v.setBackgroundDrawable(mDrawable);

And that gave me the same result as the XML background above. Now I can programmatically set the background color.

Solution 2:

I tried using Phenome's solution for Button view. But somehow it did not work.

I came up with something else: (Courtesy: Android API Demo examples)

package com.example.testApp;

import android.app.Activity;
import android.graphics.drawable.GradientDrawable;
import android.os.Bundle;
import android.view.View;

public class TetApp extends Activity {
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        View v = findViewById(R.id.btn);
        v.setBackgroundDrawable( new DrawableGradient(new int[] { 0xff666666, 0xff111111, 0xffffffff }, 0).SetTransparency(10));

    }

    public class DrawableGradient extends GradientDrawable {
        DrawableGradient(int[] colors, int cornerRadius) {
            super(GradientDrawable.Orientation.TOP_BOTTOM, colors);

            try {
                this.setShape(GradientDrawable.RECTANGLE);
                this.setGradientType(GradientDrawable.LINEAR_GRADIENT);
                this.setCornerRadius(cornerRadius);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

        public DrawableGradient SetTransparency(int transparencyPercent) {
            this.setAlpha(255 - ((255 * transparencyPercent) / 100));

            return this;
        }
    }
}

Solution 3:

Try my code below:

 int[] colors = new int[2];
            colors[0] = getRandomColor();
            colors[1] = getRandomColor();


            GradientDrawable gd = new GradientDrawable(
                    GradientDrawable.Orientation.TOP_BOTTOM, colors);

            gd.setGradientType(GradientDrawable.RADIAL_GRADIENT);
            gd.setGradientRadius(300f);
            gd.setCornerRadius(0f);
            YourView.setBackground(gd);

Method for generating random color:

public static int getRandomColor(){
    Random rnd = new Random();
    return Color.argb(255, rnd.nextInt(256), rnd.nextInt(56), rnd.nextInt(256));
}