Barcode
Barcode

Reputation: 970

change color of my ToggleButton when clicked

I have some toggle buttons that represent the days in the week.

When a user clicks on a ToggleButton i want it to switch states and change color, indicating to the user that it was been clicked.

This is what one of my ToggleButtons looks like:

<ToggleButton
    android:id="@+id/toggleButton_monday"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_marginStart="8dp"
    android:layout_marginLeft="8dp"
    android:layout_marginTop="16dp"
    android:background="@drawable/button_border"
    android:textOff="MON"
    android:textOn="MON"
    app:layout_constraintEnd_toStartOf="@+id/toggleButton_tuesday"
    app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintTop_toBottomOf="@+id/textView10" />

enter image description here

I want the button to look like this after it's clicked (i want the same border and shape, but just different color and state changed):

enter image description here


The answer here doesn't work, as i already have an android:background for my toggle buttons to show the custom border around the button.

The answer here doesn't work, as i am using a ToggleButton and not a SwitchCompat


EDIT:

Here is the current android:background i am setting my ToggleButtons with:

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle" >
    <corners
        android:radius="10dp"
        />
    <solid
        android:color="#FFFFFF"
        />
    <padding
        android:left="0dp"
        android:top="0dp"
        android:right="0dp"
        android:bottom="0dp"
        />
    <size
        android:width="75dp"
        android:height="40dp"
        />
    <stroke
        android:width="3dp"
        android:color="#878787"
        />
</shape>

EDIT: SOLUTION

Thank you @Broken and @Moustafa Shahin, i used a combination of their answers.

First i created two resource files for my ToggleButtons toggle_button_default.xml and toggle_button_checked.xml (check code above in the first EDIT). Basically, the background colors are just different in the two XMLs.

Second, i created a seletor called toggle_button_state.xml, and loaded the appropriate resources files, that i created above:

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <!-- WHEN IS CHECKED -->
    <item android:drawable="@drawable/toggle_button_default" android:state_checked="false" />

    <!-- WHEN IS NOT CHECKED -->
    <item android:drawable="@drawable/toggle_button_checked" android:state_checked="true" />

</selector>

And lastly, for my ToggleButtons, i set the toggle_button_state as the background for them:

<ToggleButton
    android:id="@+id/toggleButton_monday"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_marginStart="8dp"
    android:layout_marginLeft="8dp"
    android:layout_marginTop="8dp"
    android:background="@drawable/toggle_button_state"
    android:textOff="MON"
    android:textOn="MON"/>

In the Activity, i have an onClick method, that i can use to monitor the clicks:

class RentActivity : AppCompatActivity(), View.OnClickListener {
    override fun onClick(v: View?) {
        when(v?.id){
            R.id.toggleButton_monday ->{
                Toast.makeText(this, "Monday Clicked", Toast.LENGTH_LONG).show()
                return
            }
     ...

Upvotes: 1

Views: 3693

Answers (3)

Boken
Boken

Reputation: 5362

You have to create new file in drawable directory with list of states.

You can name it toggle_background.xml:

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <!-- WHEN IS CHECKED -->
    <item android:drawable="@color/colorPrimary" android:state_checked="false" />

    <!-- WHEN IS NOT CHECKED -->
    <item android:drawable="@color/colorAccent" android:state_checked="true" />

</selector>

Above file you can use as background of ToggleButton:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <ToggleButton
        android:id="@+id/toggleButton_monday"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="@drawable/toggle_background"
        android:textOff="ON"
        android:textOn="OFF" />

</LinearLayout>

By default button has grey border. When would you like to remove it just add:

style="?android:attr/borderlessButtonStyle"

to your ToggleButton in xml file.

You can also add OnCheckedChangeListener. If you have many buttons you can add all of them to the list, and in loop add that same listener for all of them:

import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v7.app.AppCompatActivity;
import android.widget.CompoundButton;
import android.widget.ToggleButton;

import java.util.ArrayList;
import java.util.List;

public class MainActivity extends AppCompatActivity {

    private List<ToggleButton> listOfButtons = new ArrayList<>();

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

        // Add ToggleButtons to list
        listOfButtons.add(findViewById(R.id.toggleButton_monday));

        // Create listener for all of them
        CompoundButton.OnCheckedChangeListener listener = (buttonView, isChecked) -> {
            // Do something
        };


        // Add listener to all od buttons
        for (ToggleButton button : listOfButtons) {
            button.setOnCheckedChangeListener(listener);
        }
    }
}

Upvotes: 2

Christian Boler
Christian Boler

Reputation: 161

If you're looking for an elegant way to do this, you might want to try using a GridView....

<GridView
    android:id="@+id/gridview"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:gravity="center"
    android:columnWidth="100dp"
    android:numColumns="auto_fit"
    android:verticalSpacing="24dp"
    android:horizontalSpacing="10dp"
    android:stretchMode="spacingWidthUniform"
    />

...which will allow you to populate your layout with items in a way that lets you iterate through them more easily. You can create a custom Adapter and assign it to the gridview:

GridView gridview = findViewById(R.id.gridview);
MyCustomAdapter _Adapter = new MyCustomAdapter(getApplicationContext());
gridview.setAdapter(_Adapter);

Which will allow you to set a single onClickListener for all your buttons in one place:

gridview.setOnItemClickListener((parent, view, position, id) -> {
        _Adapter.toggleItem(position);
    });

You can find an in depth tutorial on creating a custom gridview adapter here

Upvotes: 0

Moustafa Shahin
Moustafa Shahin

Reputation: 132

you can create 2 background resource files and change them depends on status :

ToggleButton toggle = (ToggleButton) findViewById(R.id.togglebutton);
toggle.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
    if (isChecked) {
        // The toggle is enabled
        //the background resource which mean status is enable
    } else {
        // The toggle is disabled
        //the background resource which mean status is disabled
    }
}

});

Upvotes: 2

Related Questions