javaandroidandroid-layoutandroid-radiobutton

How to change background color/shape of a Radiobutton when selected/deselected


I am adding radiobuttons programatically to a RadioGroup in a for loop. I want my buttons to have a certain background color when not checked, and another when they are checked (only one can be selected at once). My problem is that I also want this background to be a rounded rectangle. I have it working partially, but whenever I select an answer, it will set that button's background to white, but it won't reset any of the other buttons.

I understand that I need some type of selector object, to add the toggle behavior that is expected from the radiogroup. I was able to find some examples of that, but they only showed how to set a solid color as a background. I need to use this rounded corner shape. So, my trouble is figuring out how to blend the two. I could be going about this completely wrong. If there is a better approach to achieving what I want, I would prefer to use that rather than salvage what I've already tried.

I was able to get close by creating two XML files, each with a shape object and its own background color. If a radiobutton is selected, its style gets set to the radio_button_checked" style. But, I know I am approaching this wrong because the other checked button does not toggle off. I can basically click all of the buttons and get them all to have white backgrounds. I know there is a better way to do this, I just don't know what it is

Here is the loop where I add the buttons, along with the change listener for radiogroup rg (rg is my RadioGroup and answers is just a HashMap of strings. They don't affect anything related to this problem. The buttonTintList line is just there to change circle color)

for(int i = 0; i < answers.size(); i++)
    {
        RadioButton rb = new RadioButton(context);
        rb.setTextColor(ContextCompat.getColor(context, R.color.colorPrimaryDark));


        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            rb.setButtonTintList(ColorStateList.valueOf(ContextCompat.getColor( context, R.color.colorAccent)));
        }
        rb.setBackground(context.getResources().getDrawable(R.drawable.radiobutton_style_unchecked));
        rb.setText(answers.get(i));
        rb.setWidth(800);
        rb.setHeight(150);
        rb.setTextSize(18);
        rb.setLayoutParams(params);
        rg.addView(rb);
    }
    /*  Store the answer */
    rg.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() {
        @Override
        public void onCheckedChanged(RadioGroup group, int checkedId) {
            RadioButton rb= (RadioButton)group.findViewById(checkedId);
            answer = rb.getText().toString();

            rb.setBackground(context.getResources().getDrawable(R.drawable.radiobutton_style_checked));

        }
    });

Here is the XML for unchecked buttons (radiobutton_style_unchecked.xml)

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="rectangle" >
<corners android:radius="6dp" />
<gradient
    android:angle="45"
    android:centerColor="@color/colorPrimaryLight"
    android:centerX="35%"
    android:endColor="@color/colorPrimaryLight"
    android:startColor="@color/colorPrimaryLight"
    android:type="linear" />

<padding
    android:bottom="5dp"
    android:left="0dp"
    android:right="0dp"
    android:top="5dp" />


</shape>

The style for checked buttons is exactly the same, but with white instead of colorPrimaryLight

Here is what it looks like with nothing selected: 1

Here is what it looks like when one item is selected. 2

And this is what happens when I select more than one 3


Solution

  • Try this

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="@android:color/holo_blue_light"
        android:orientation="vertical">
    
        <RadioGroup
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="vertical">
    
            <RadioButton
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_margin="10dp"
                android:background="@drawable/radio_background"
                android:padding="10dp"
                android:text="Yes" />
    
            <RadioButton
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_margin="10dp"
                android:background="@drawable/radio_background"
                android:padding="10dp"
                android:text="No" />
    
        </RadioGroup>
    
    </LinearLayout>
    

    @drawable/radio_background

    <?xml version="1.0" encoding="utf-8"?>
    <selector xmlns:android="http://schemas.android.com/apk/res/android">
        <item android:drawable="@android:color/white" android:state_checked="true" />
        <item android:drawable="@color/colorAccent" android:state_checked="false" />
    </selector>
    

    OUTPUT

    enter image description here

    UPDATE

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="@android:color/holo_blue_light"
        android:orientation="vertical">
    
        <RadioGroup
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="vertical">
    
            <RadioButton
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_margin="10dp"
                android:background="@drawable/test"
                android:padding="10dp"
                android:text="Yes" />
    
            <RadioButton
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_margin="10dp"
                android:background="@drawable/test"
                android:padding="10dp"
                android:text="No" />
    
        </RadioGroup>
    
    </LinearLayout>
    

    @drawable/test

    <?xml version="1.0" encoding="utf-8"?>
    <selector xmlns:android="http://schemas.android.com/apk/res/android" android:exitFadeDuration="@android:integer/config_shortAnimTime">
    
        <item android:drawable="@drawable/radio_selected" android:state_checked="true" />
        <item android:drawable="@drawable/radio_normal" />
    
    </selector>
    

    @drawable/radio_selected

    <?xml version="1.0" encoding="utf-8"?>
    <shape xmlns:android="http://schemas.android.com/apk/res/android"
        android:shape="rectangle">
        <corners android:radius="20dp" />
        <solid android:color="@android:color/white" />
        <padding
            android:bottom="5dp"
            android:left="0dp"
            android:right="0dp"
            android:top="5dp" />
    
    
    </shape>
    

    @drawable/radio_normal

    <?xml version="1.0" encoding="utf-8"?>
    <shape xmlns:android="http://schemas.android.com/apk/res/android"
        android:shape="rectangle">
        <corners android:radius="20dp" />
        <solid android:color="@color/colorAccent" />
        <padding
            android:bottom="5dp"
            android:left="0dp"
            android:right="0dp"
            android:top="5dp" />
    
    </shape>
    

    OUTPUT

    enter image description here