Friday 12 September 2014

Creating Dynamic Checkbox in Android

Creating Dynamic Checkbox in Android

In order to create dynamic checkbox in Android, the following steps are to be followed:--

1. The checkboxes that are to be created dynamically depends on the number of data items which may come from a remote server or your own local database. In this situation i have used a string array resource which contains a array of countries. The resource file is contained in the values sub directory  of the resources directory. This string array is defined in the file strings.xml.

    <string-array name="Countries">
        <item>India</item>
        <item>Pakistan</item>
        <item>US</item>
        <item>UK</item>
        <item>Switzerland</item>
        <item>Spain</item>
        <item>France</item>
        <item>Germany</item>
        <item>Finland</item>
        <item>China</item>
        <item>Japan</item>
        <item>Thailand</item>
        <item>Singapore</item>
        <item>South Africa</item>
        <item>Russia</item>
    </string-array>

2. The next step is to create a layout file. You can see that ScrollView is used , it is basically used in order to scroll vertically through the list of checkboxes.
activity_dynamic_checkboxes.xml

<RelativeLayout 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"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context=".DynamicCheckboxes" >

    <LinearLayout android:id="@+id/childlyt"
                  android:layout_width="match_parent"
                  android:layout_height="wrap_content"
                  android:orientation="vertical">
        
        <Button android:id="@+id/saveProceed"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="@string/saveProceed"
                android:layout_gravity="center_horizontal"
                android:background="@drawable/custombutton"/>
        
              
    </LinearLayout>"
    <ScrollView android:id="@+id/scrlvw"
                android:layout_width="match_parent"
                android:layout_height="40dp"
                android:layout_below="@+id/childlyt"
                android:fillViewport="true"
                android:layout_centerHorizontal="true"
                android:paddingTop="9dp"
                >
    <LinearLayout android:id="@+id/chkboxlyt"
                  android:layout_width="wrap_content"
                  android:layout_height="wrap_content"
                  android:orientation="vertical">
                  
       <View android:id="@+id/customline"
             android:layout_width="fill_parent"
             android:layout_height="5dp"
             android:background="@color/textcolr"/> 
        
    </LinearLayout>
  </ScrollView>  
</RelativeLayout>

3. Finally the code :--
   3.1 Code for dynamic creation of checkbox. What happens in this code is that first of all we obtain the array of countries from the string array resources. Then a array is created in order to hold the checkboxes created dynamically/programmatically.
String [] countries_array = getResources().getStringArray(R.array.Countries);


CheckBox[] dynamicCheckBoxes = new CheckBox[countries_array.length];

After the creation of the array of dynamic checkboxes and retrieving from the string array resources, the array of countries, the id of the layout in which the checkboxes is to be displayed is obtained and then in the for loop the checkboxes are created dynamically and it's properties are set. Then the checkbox i.e. created dynamically is added to the layout. In order to handle the events i.e. check and uncheck related to checkbox, the listener for a checkbox is set i.e. 


cb.setOnCheckedChangeListener(this);

For the above statement to work properly and not throw compiler error you have to implement i.e your activity must implement CompoundButton.OnCheckedChangeListener interface.

LinearLayout checkboxLayout = (LinearLayout)findViewById(R.id.chkboxlyt);
for(int i=0;i<dynamicCheckBoxes.length;i++){
CheckBox cb = new CheckBox(this);
cb.setText(countries_array[i]);
cb.setTextSize(27);
cb.setTextColor(Color.rgb(150, 190, 200));
cb.setTypeface(Typeface.MONOSPACE);
cb.setButtonDrawable(R.drawable.checkboxselector);

dynamicCheckBoxes[i]=cb;
checkboxLayout.addView(cb);
cb.setOnCheckedChangeListener(this);


}

The callback method implementation for  setOnCheckedChangeListener of the checkbox

public void onCheckedChanged(CompoundButton cb, boolean isChecked){
String checkedText = cb.getText()+"";

if(isChecked){
checkedCountries.add(checkedText);
Toast.makeText(this, cb.getText()+" is checked!!!", Toast.LENGTH_SHORT).show();
} else {
checkedCountries.remove(checkedText);
Toast.makeText(this, cb.getText()+" is not checked!!!", Toast.LENGTH_SHORT).show();
}


}

In this callback method onCheckedChanged the state of the checkbox is determined i.e if the checkbox is checked or not. If the checkbox is checked then the text related to the checkbox i.e. checked is obtained and added to the ArrayList and then the country name i.e. checked is displayed using Toast. If the checkbox previously checked is unchecked then it is removed from the list. A toast is displayed i.e. the name of the checkbox i.e. unchecked.

4. Handling the configuration changes. In this the configuration change that may happen is orientation change from portrait to landscape. So when there is a change in orientation the checked checkboxes must not be lost i.e. the checkboxes that were checked in portrait mode must be retained in landscape orientation.

So in order to handle successfully orientation changes override the onSaveInstanceState callback method.
In this method initialize the flag to 1 and save the checkedCountries ArrayList and the flag in the bundle.

public void onSaveInstanceState(Bundle savedState){
super.onSaveInstanceState(savedState);
flag=1;
savedState.putStringArrayList("checkedCountries", checkedCountries);
savedState.putInt("savedflag", flag);
}


}

Now to restore the saved state in the new configuration do the following thing:--
Define a ArrayList of checked countries and then obtain from the bundle the arraylist of checked countries and the flag which determine whether orientation has taken place or not. 
Check if the flag is 1 then loop through the array of dynamic checkboxes and then set the checkboxes as checked which were previously checked by using the toggle button of the checkbox.

int flag=0;
ArrayList <String>retrievedCheckedCountriesList;

if(savedInstanceState!=null){
retrievedCheckedCountriesList = savedInstanceState.getStringArrayList("checkedCountries");
flag = savedInstanceState.getInt("savedflag");
}
String [] countries_array = getResources().getStringArray(R.array.Countries);
CheckBox[] dynamicCheckBoxes = new CheckBox[countries_array.length];
LinearLayout checkboxLayout = (LinearLayout)findViewById(R.id.chkboxlyt);
for(int i=0;i<dynamicCheckBoxes.length;i++){
CheckBox cb = new CheckBox(this);
cb.setText(countries_array[i]);
cb.setTextSize(27);
cb.setTextColor(Color.rgb(150, 190, 200));
cb.setTypeface(Typeface.MONOSPACE);
cb.setButtonDrawable(R.drawable.checkboxselector);

dynamicCheckBoxes[i]=cb;
checkboxLayout.addView(cb);
cb.setOnCheckedChangeListener(this);
}
if(flag!=0){
for(CheckBox cb:dynamicCheckBoxes){
for(int i=0; i<retrievedCheckedCountriesList.size();i++){
if((cb.getText()+"").equals(retrievedCheckedCountriesList.get(i))){
cb.toggle();
}
}
 }
}


}

DynamicCheckboxes.java
package com.anroid.androprac;

import java.util.ArrayList;
import android.app.Activity;
import android.content.Intent;
import android.graphics.Color;
import android.graphics.Typeface;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.CompoundButton;
import android.widget.LinearLayout;
import android.widget.Toast;

public class DynamicCheckboxes extends Activity implements CompoundButton.OnCheckedChangeListener {
int flag=0;
ArrayList <String>checkedCountries = new ArrayList<String>();
ArrayList <String>retrievedCheckedCountriesList;
Button saveProceed;
@Override
protected void onCreate(Bundle savedInstanceState)  {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_dynamic_checkboxes);
if(savedInstanceState!=null){
retrievedCheckedCountriesList = savedInstanceState.getStringArrayList("checkedCountries");
flag = savedInstanceState.getInt("savedflag");
}
saveProceed = (Button)findViewById(R.id.saveProceed);
saveProceed.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(DynamicCheckboxes.this, ActivityD.class);
intent.putStringArrayListExtra("checkedVals", checkedCountries);
startActivity(intent);
}
});
String [] countries_array = getResources().getStringArray(R.array.Countries);
CheckBox[] dynamicCheckBoxes = new CheckBox[countries_array.length];
LinearLayout checkboxLayout = (LinearLayout)findViewById(R.id.chkboxlyt);
for(int i=0;i<dynamicCheckBoxes.length;i++){
CheckBox cb = new CheckBox(this);
cb.setText(countries_array[i]);
cb.setTextSize(27);
cb.setTextColor(Color.rgb(150, 190, 200));
cb.setTypeface(Typeface.MONOSPACE);
cb.setButtonDrawable(R.drawable.checkboxselector);

dynamicCheckBoxes[i]=cb;
checkboxLayout.addView(cb);
cb.setOnCheckedChangeListener(this);
}
if(flag!=0){
for(CheckBox cb:dynamicCheckBoxes){
for(int i=0; i<retrievedCheckedCountriesList.size();i++){
if((cb.getText()+"").equals(retrievedCheckedCountriesList.get(i))){
cb.toggle();
}
}
}
}
}
public void onCheckedChanged(CompoundButton cb, boolean isChecked){
String checkedText = cb.getText()+"";

if(isChecked){
checkedCountries.add(checkedText);
Toast.makeText(this, cb.getText()+" is checked!!!", Toast.LENGTH_SHORT).show();
} else {
checkedCountries.remove(checkedText);
Toast.makeText(this, cb.getText()+" is not checked!!!", Toast.LENGTH_SHORT).show();
}
}

public void onSaveInstanceState(Bundle savedState){
super.onSaveInstanceState(savedState);
flag=1;
savedState.putStringArrayList("checkedCountries", checkedCountries);
savedState.putInt("savedflag", flag);
}
}

5. The selector file which is used to select the drawable based upon the state of the checkbox.
The selector which is used for checkbox selection.
checkboxselector.xml 

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

</selector>

The Final Output :--

In Portrait Mode




In Landscape Mode






The selected countries


The drawables used in this :--
checked.png
                                            unchecked.png

Finally this concludes the Creation of dynamic checkbox Android.
Happy coding :)

No comments:

Post a Comment