ZOFTINO.COM android and web dev tutorials

Android UI Control Checkbox

To capture user selections out of given multiple options or to capture input for fields which have only two states, Checkbox is used. Android Checkbox is a subclass of CompoundButton which intern is a subclass of Button, so it inherits all the attributes from CompoundButton, Button, TextView and View.

Adding Checkbox to UI

You can add Checkbox to android UI by defining CheckBox element in xml manually or using android studio layout design tool which can be accessed by opening layout xml and clicking design tab. Below xml is an example of simple CheckBox definition.

<CheckBox
    android:id="@+id/checkBox2"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="CheckBox" />

Checkbox Attributes

To define checkbox, main attributes which need to be used are focusable, clickable, textAppearance, textColor, gravity, background, button, and buttonTint. These properties are usually set by device default styles which you can customize to change appearance of checkbox.

Chckbox Styles

Android platform provides styles including material styles for check box. If you set application theme to one of the app compact material themes, Widget.AppCompat.CompoundButton.CheckBox style is applied to checkbox.

Below screen shot shows checkboxes both in checked and unchecked states when application theme is set to Theme.AppCompat.

android checkbox app compact style

Customizing CheckBox Styles for Application

You can customize checkbox styles for entire application or specific check box. To change fill colors for all controls including checkbox, you need to set colorAccent to the desired color in your custom app-compact theme that will be applied to your application.

Below are custom app compact theme with colorAccent set to custom color and screen shot showing checkboxes in both states after applying the custom theme to application.

 <style name="MyAppTheme" parent="Theme.AppCompat">
    <item name="colorAccent">#6c1164</item>
</style>
android checkbox app compact style custom color

Customizing Styles for Individual CheckBox

To customize individual checkboxes, first create custom theme by inheriting app compact checkbox theme and then apply it to individual checkbox using theme attribute.

Customizing checkbox color

To change checkbox color when it is in unchecked state, you need to set colorControlNormal attribute to the desired color. To change checkbox color when it is in checked state, attribute colorControlActivated needs to be set. You can make checkbox show different color when it is touched or highlighted using colorControlHighlight attribute.

If you want same color applied to checkbox in both states, you can use buttonTint attribute, but the style containing this property needs to be applied to checkbox as style.

Custom checkbox style.

<style name="MyCheckbox" parent="@style/Widget.AppCompat.CompoundButton.CheckBox">
    <item name="android:colorControlNormal">#ffd600</item>
    <item name="android:colorControlActivated">#0091ea</item>
    <item name="android:colorControlHighlight">#c51162</item>
    <item name="android:textAppearance">@style/TextAppearance.AppCompat</item>
</style>

Applying custom style to checkbox.

<CheckBox
    android:id="@+id/checkBox"
    android:text="CheckBoxOne"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:theme="@style/MyCheckbox"/>

Checkbox custom style output.

android checkbox checked and unchecked custom color

Checkbox text color

To change text color of checkbox text, you can use textColorPrimaryDisableOnly or textColor attribute. If you define textColor style in your custom theme to change checkbox text color, it won’t work if style is applied as theme. You need to apply the custom style to check box using both style and theme in order for check box colors and checkbox text color to be effective. It is better to create two styles one containing check box colors that will be used as theme and second style containing text color for check box text that will be used as style, as shown in the below example. Or you can use textColorPrimaryDisableOnly attribute in custom style and apply it as theme to application or checkbox.

<style name="MyChkTextColor">
    <item name="android:textColor">#7ca011</item>4
</style>
 
<CheckBox
	. . .
    android:theme="@style/MyCheckbox"
    style="@style/MyChkTextColor"/>
android checkbox text color

Customizing checkbox button shape

You can customize CheckBox shape by defining drawable as xml in res/drawable folder and setting button attribute of CheckBox to the drawable.

Below is an example of drawable xml definition for CheckBox. It uses cust_chk_select and cust_chk checkbox images for both states, which need to be saved in res/drawable folder.

<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:state_checked="true" android:drawable="@drawable/cust_chk_select" />
    <item android:drawable="@drawable/cust_chk" />
</selector>

Using custom drawable in checkbox style.

 <style name="MyCustomCheckbox" parent="@style/Widget.AppCompat.CompoundButton.CheckBox">
    <item name="android:button">@drawable/my_checkbox</item>
    <item name="android:textAppearance">@style/TextAppearance.AppCompat</item>
</style>
 

Custom CheckBox output.

android checkbox custom drawable

If you need a kind of checkbox that uses colors instead of check mark to indicate whether a checkbox is selected or not, then you can define shapes as xml and use them as drawables as explained below.

Shape with one color saved in res/drawable as my_chk_checked.xml

 <shape xmlns:android="http://schemas.android.com/apk/res/android">
    <stroke android:width="2px" android:color="#1b5e20" />
    <size android:height="20dp" android:width="20dp"/>
</shape>
 

Second shape with different color saved in res/drawable as my_chk_normal.xml

 <shape xmlns:android="http://schemas.android.com/apk/res/android">
    <stroke android:width="2px" android:color="#ffd600" />
    <size android:height="20dp" android:width="20dp"/>
</shape>
 

Selector drawable xml saved in res/drawable as my_chk.xml

<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:state_checked="true" android:drawable="@drawable/my_chk_checked" />
    <item android:drawable="@drawable/my_chk_normal" />
</selector>
 

Setting the button attribute of checkbox to the selector.

 <CheckBox
	. . .
    android:button="@drawable/my_chk"/> 

Checkbox Listener

Checkbox event can be handled by setting onClick attribute of Checkbox element in layout xml. To do that, first define a method as shown below and set it as a value for onClick attribute.

public void checkBoxClicked(View v){
    Toast.makeText(MainActivity.this, "Checkbox clicked "+v.getId(), Toast.LENGTH_LONG).show();
}

Checkbox click event can also be handled by adding on click listener to check box as shown below.

CheckBox chkBox = (CheckBox) findViewById(R.id.checkBox);

chkBox.setOnClickListener( new View.OnClickListener(){
   @Override
   public void onClick(View view) {
   Toast.makeText(MainActivity.this, "Checkbox clicked "+view.getId(), Toast.LENGTH_LONG).show();
    }
});

Setting Checkbox State

CheckBox state can be changed using checked attribute in layout xml. By default checkbox is unchecked. You can make it checked by setting checked attribute to true.

 <CheckBox
	. . .
    android:checked="true" />

You can change the state of checkbox using setChecked method of Checkbox as shown below or you can use toggle method also.

CheckBox checkBoxOne = (CheckBox) findViewById(R.id.checkbox1);
if (!checkBoxOne.isChecked()) {
     checkBoxOne.setChecked(true);
} 

Listview Checkbox

In your app if there are multiple options to be displayed for user selection, then presenting multiple options can be done using ListView and CheckBox. Below example shows how to display checkboxes with ListView by taking ecommerce category search filter as an example.

android listview checkbox example

Activity layout

Activity layout contains ListView.

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.example.srinu.stylesthemes.CategoryFilterActivity
">
    <ListView android:id= "@+id/category_lst"
        android:layout_width="match_parent"
        android:layout_height="match_parent"></ListView>
</LinearLayout>

ListView item layout

ListView item layout is used to display each row of options and it contains TextView and CheckBox

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout 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">

    <TextView
        android:id="@+id/cat_name"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginStart="16dp"
        android:layout_marginTop="8dp"
        android:ems="10"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <CheckBox
        android:id="@+id/cat_select"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginEnd="8dp"
        android:layout_marginStart="8dp"
        app:layout_constraintBaseline_toBaselineOf="@+id/cat_name"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toEndOf="@+id/cat_name" />
</android.support.constraint.ConstraintLayout>

Activity

package com.example.srinu.stylesthemes;

import android.app.Activity;
import android.os.Bundle;
import android.widget.ListView;

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

public class CategoryFilterActivity extends Activity {

    private ListView lstView;

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

        lstView = (ListView) findViewById(R.id.category_lst);

        //get data and initialize list view adapter
        CategoryListAdapter catLstAdapter = new CategoryListAdapter(getCatSelection(), this);
        lstView.setAdapter(catLstAdapter);
    }

    private List<Model> getCatSelection(){
        List<Model> modelList = new ArrayList<Model>();
        modelList.add(new Model("Men Clothing", false));
        modelList.add(new Model("Women Clothing", true));
        modelList.add(new Model("Kids Fashion", false));
        modelList.add(new Model("Baby Clothing", true));
        modelList.add(new Model("Toys", false));
        modelList.add(new Model("Baby Toys", true));
        modelList.add(new Model("Footwear", false));
        modelList.add(new Model("Appliance", false));
        modelList.add(new Model("Electronics", true));
        modelList.add(new Model("Kitchen", false));
        modelList.add(new Model("Home", false));
        modelList.add(new Model("Furnishing", false));
        modelList.add(new Model("Furniture", false));
        modelList.add(new Model("Tools", false));
        modelList.add(new Model("Luggage", false));

        return modelList;
    }
}

ListView Custom Adapter

 package com.example.srinu.stylesthemes;

import android.content.Context;
import android.support.annotation.NonNull;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.CheckBox;
import android.widget.CompoundButton;
import android.widget.TextView;
import android.widget.Toast;

import java.util.List;

public class CategoryListAdapter extends ArrayAdapter {

    private List<Model> dataList;
    Context mContext;

    private static class ViewHolder {
        TextView categoryName;
        CheckBox selection;
    }

    public CategoryListAdapter(List<Model> dataLst, Context context) {
        super(context, R.layout.listview_item, dataLst);
        this.dataList = dataLst;
        this.mContext = context;
    }

    @Override
    public int getCount() {
        return dataList.size();
    }

    @Override
    public Model getItem(int position) {
        return dataList.get(position);
    }


    @Override
    public View getView(int position, View view, @NonNull ViewGroup parent) {

        final int itemPosition = position;
        ViewHolder viewHolder;
        final View viewOut;

        if (view != null) {
            viewHolder = (ViewHolder) view.getTag();
            viewOut = view;
        } else {
            viewHolder = new ViewHolder();
            view = LayoutInflater.from(parent.getContext())
                    .inflate(R.layout.listview_item, parent, false);

            TextView categoryName = (TextView) view.findViewById(R.id.cat_name);
            CheckBox selection = (CheckBox) view.findViewById(R.id.cat_select);

            //checkbox event handling
            selection.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
                @Override
                public void onCheckedChanged(CompoundButton buttonView,
                                             boolean isChecked) {
                    if (isChecked) {
                        Toast.makeText(CategoryListAdapter.this.mContext,
                                "selected item "+itemPosition, Toast.LENGTH_LONG).show();
                    } else {

                    }
                }
            });

            viewHolder.categoryName = categoryName;
            viewHolder.selection = selection;

            viewOut = view;
            view.setTag(viewHolder);

        }

        Model item = getItem(position);

        viewHolder.categoryName.setText(item.getCategory());
        viewHolder.selection.setChecked(item.isSelected());

        return viewOut;
    }
}