javaandroidbuttondrawable

How to Implement a GradientDrawable object in Main Activity


I trying to create a traffic application. its very simple just a label and button. I wanted the label to be in a circle shape rather than square so I implemented the following in the main activity:

GradientDrawable drawable = new GradientDrawable();
drawable.setShape(GradientDrawable.OVAL);
drawable.setColor(getResources().getColor(R.color.red));

light = findViewById(R.id.traffic_light_circle);
light.setBackground(drawable);
change=findViewById(R.id.change);

However I am having trouble implementing the button. I need to implement an if else statement to switch between the colors. But I don't know how to call for the drawable object. each time I try to call it, it gives me an error. How should I approach this.

I tried the following in terms of the button but didn't get a result.

change.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) { //on button click
            GradientDrawable drawable = (GradientDrawable) light.getBackground();

            int color = drawable.getColor();
            if (color == getResources().getColor(R.color.red)) {
                drawable.setColor(getResources().getColor(R.color.yellow));
                light.setBackground(drawable);}

Solution

  • From Android 7.0 (API level 24) and above the GradientDrawable has a public method getColor() which returns a ColorStateList and from there you can retrieve the default color using the getDefaultColor() method. Also to get a color from your resources it is better to use the ContextCompat.getColor(Context context, @ColorRes int id) method which supports backward compatibility instead of the getResources().getColor(@ColorRes int id). So based on your example you can change the GradientDrawable color on every button click to the correct traffic color like the below example:

    public class MainActivity extends AppCompatActivity {
    
        TextView light;
        Button change;
        int previousColor = 0;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
    
            light = findViewById(R.id.traffic_light_circle);
            change = findViewById(R.id.change);
    
            //create the GradientDrawable initially to red color
            GradientDrawable drawable = new GradientDrawable();
            drawable.setShape(GradientDrawable.OVAL);
            drawable.setColor(ContextCompat.getColor(this, R.color.red));
            light.setBackground(drawable);
    
            //set the previous color state to red initially
            previousColor = ContextCompat.getColor(this, R.color.red);
            change.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v)
                {
                    GradientDrawable drawable = (GradientDrawable) light.getBackground();
                    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N)
                    {
                        if(drawable.getColor()!=null)
                        {
                            int color = drawable.getColor().getDefaultColor();
                            //current color is red (go to yellow)
                            if (color == ContextCompat.getColor(v.getContext(), R.color.red))
                            {
                                drawable.setColor(ContextCompat.getColor(v.getContext(), R.color.yellow));
                                light.setBackground(drawable);
                                previousColor = ContextCompat.getColor(v.getContext(), R.color.red);
                            }
                            //current color is green (go to yellow)
                            else if(color == ContextCompat.getColor(v.getContext(), R.color.green))
                            {
                                drawable.setColor(ContextCompat.getColor(v.getContext(), R.color.yellow));
                                light.setBackground(drawable);
                                previousColor = ContextCompat.getColor(v.getContext(), R.color.green);
                            }
                            //current color is yellow and the previous color was red (go to green)
                            else if(color == ContextCompat.getColor(v.getContext(), R.color.yellow) && previousColor == ContextCompat.getColor(v.getContext(), R.color.red))
                            {
                                drawable.setColor(ContextCompat.getColor(v.getContext(), R.color.green));
                                light.setBackground(drawable);
                                previousColor = ContextCompat.getColor(v.getContext(), R.color.yellow);
                            }
                            //current color is yellow and the previous color was green (go to red)
                            else if(color == ContextCompat.getColor(v.getContext(), R.color.yellow) && previousColor == ContextCompat.getColor(v.getContext(), R.color.green))
                            {
                                drawable.setColor(ContextCompat.getColor(v.getContext(), R.color.red));
                                light.setBackground(drawable);
                                previousColor = ContextCompat.getColor(v.getContext(), R.color.yellow);
                            }
                        }
                    }
                }
            });
        }
    }
    

    The variable of previousColor in the above example is necessary when the current state is yellow to identify the next color state red or green.