| Author |
Message |
B_Thax Freshman


Joined: 17 Jul 2008 Posts: 9 Location: Palma de Mallorca
|
Posted: Sat Apr 11, 2009 6:37 pm Post subject: Extended Checkbox List :: Extension of Checkbox Text List tu |
|
|
Extended Checkbox List :: Extension of Checkbox Text List tutorial
What you learn: You will learn how to create new list adapters with several widgets in it and how you can catch selection events on them.
Difficulty: 2 of 5
What it will look like:
Description:
This tutorial grew from another tutorial here which dealt with making lists with icons attached to each list item. (Checkbox Text List tutorial).
The original tutorial had several drawbacks:
* Missing right 'onCLick' handling for containing widgets
* No selection when using the arrow keys
* Checkbox will loose state while scrolling
* Initial values missed sometimes
The next tutorial will fix all those problems. I'll add code because the base code it two tutorials away, so it's useful to get it all.
1.
In order to be able to configure our list we need a class that holds all information each of our rows must have. It's the same taken from the previus tut but with a name change:
| Java: |
public class ExtendedCheckBox implements Comparable<ExtendedCheckBox>
{
private String mText = "";
private boolean mChecked;
public ExtendedCheckBox(String text, boolean checked)
{
/* constructor */
mText = text;
mChecked = checked;
}
public void setChecked(boolean value)
{
this.mChecked = value;
}
public boolean getChecked()
{
return this.mChecked;
}
public String getText() {
return mText;
}
public void setText(String text) {
mText = text;
}
/** Make CheckBoxifiedText comparable by its name */
//@Override
public int compareTo(ExtendedCheckBox other)
{
if(this.mText != null)
return this.mText.compareTo(other.getText());
else
throw new IllegalArgumentException();
}
}
|
2.
The next step will be to create our 'View'. The view is responsible to draw a single row in our elemnt list. Also the view handles internally when the checkbox should be toggled. The stuff that needs to be added are 2 OnClickListener's, one for the checkbox and one for the view itself.
The checkboxs listener is used to update our ExtendedCheckBox after the user clicked the checkbox, this way our data inthe checkbox and the ExtendedCheckBox will remein consitent.
The second listener will be used to handle clicks directly in the view, so that we will able to change the checkbox not only by clicking on it.
Here is the code:
| Java: |
import android.content.Context;
import android.view.View;
import android.widget.CheckBox;
import android.widget.LinearLayout;
import android.widget.TextView;
public class ExtendedCheckBoxListView extends LinearLayout {
private TextView mText;
private CheckBox mCheckBox;
private ExtendedCheckBox mCheckBoxText;
public ExtendedCheckBoxListView(Context context, ExtendedCheckBox aCheckBoxifiedText) {
super(context);
// Set orientation to be horizontal
this.setOrientation(HORIZONTAL);
mCheckBoxText = aCheckBoxifiedText;
mCheckBox = new CheckBox(context);
mCheckBox.setPadding(0, 0, 20, 0);
// Set the initial state of the checkbox.
mCheckBox.setChecked(aCheckBoxifiedText.getChecked());
// Set the right listener for the checkbox, used to update
// our data holder to change it's state after a click too
mCheckBox.setOnClickListener( new OnClickListener()
{
/**
* When clicked change the state of the 'mCheckBoxText' too!
*/
@Override
public void onClick(View v) {
mCheckBoxText.setChecked(getCheckBoxState());
}
});
// Add the checkbox
addView(mCheckBox, new LinearLayout.LayoutParams(
LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
mText = new TextView(context);
mText.setText(aCheckBoxifiedText.getText());;
addView(mText, new LinearLayout.LayoutParams(
LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
// Remove some controls in order to prevent a strange flickering when clicking on the TextView!
mText.setClickable(false);
mText.setFocusable(false);
mText.setFocusableInTouchMode(false);
setOnClickListener( new OnClickListener()
{
/**
* Check or unchecked the current checkbox!
*/
@Override
public void onClick(View v) {
toggleCheckBoxState();
}
});
}
public void setText(String words) {
mText.setText(words);
}
public void toggleCheckBoxState()
{
setCheckBoxState(!getCheckBoxState());
}
public void setCheckBoxState(boolean bool)
{
mCheckBox.setChecked(bool);
mCheckBoxText.setChecked(bool);
}
public boolean getCheckBoxState()
{
return mCheckBox.isChecked();
}
}
|
3.
Now we need have to create our adapter, which will be the link between the actual data and the layout. The difference bewteen our adapter and the one in the previus tutorial that we never cache the view, we always create a new one. Once a new item is visible our layout will call getView(), the problem is that if we use the old view we could get some problems on data persistence. So the securest way is to build a new view.
| Java: |
import java.util.ArrayList;
import java.util.List;
import android.content.Context;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
public class ExtendedCheckBoxListAdapter extends BaseAdapter {
/** Remember our context so we can use it when constructing views. */
private Context mContext;
private List<ExtendedCheckBox> mItems = new ArrayList<ExtendedCheckBox>();
/**
*
* @param context - Render context
*/
public ExtendedCheckBoxListAdapter(Context context) {
mContext = context;
}
/**
* Add a new Item at the end of the exiting ones
* @param it - New item to be added
*/
public void addItem(ExtendedCheckBox it) {
mItems.add(it);
}
/**
* Will force to use a list of items
* @param lit - List of items to be used
*/
public void setListItems(List<ExtendedCheckBox> lit) {
mItems = lit;
}
/**
* @return The number of items this adapter offers
*/
public int getCount() {
return mItems.size();
}
/**
* Return item at a specific position
*/
public Object getItem(int position) {
return mItems.get(position);
}
/**
* Returns the position of an element
*/
public int GetPosition( ExtendedCheckBox item ) {
int count = getCount();
for ( int i = 0; i < count; i++ )
{
if ( item.compareTo((ExtendedCheckBox)getItem(i)) == 0 )
return i;
}
return -1;
}
/**
* Set selection of an item
* @param value - true or false
* @param position - position
*/
public void setChecked(boolean value, int position) {
mItems.get(position).setChecked(value);
}
/**
* Select all elements
*/
public void selectAll() {
for(ExtendedCheckBox cboxtxt: mItems)
cboxtxt.setChecked(true);
/* Things have changed, do a redraw. */
this.notifyDataSetInvalidated();
}
/**
* Deselect all elements
*/
public void deselectAll() {
for(ExtendedCheckBox cboxtxt: mItems)
cboxtxt.setChecked(false);
/* Things have changed, do a redraw. */
this.notifyDataSetInvalidated();
}
/**
* Decides if all items are selectable
* @return - true or false
*/
public boolean areAllItemsSelectable() {
return false;
}
/**
* Use the array index as a unique id
*/
public long getItemId(int position) {
return position;
}
/**
* Do not recycle a view if one is already there, if not the data could get corrupted and
* the checkbox state could be lost.
* @param convertView The old view to overwrite
* @returns a CheckBoxifiedTextView that holds wraps around an CheckBoxifiedText */
public View getView(int position, View convertView, ViewGroup parent ){
return new ExtendedCheckBoxListView(mContext, mItems.get(position));
}
}
|
4.
The final step (of code) is to build our activity. It's important to build a list activity and to add some functionalty to be able to toggle the checkbox while navigating with the arrows. You could create it as a base class for your lists so you reuse the code.
Every ListActivity has a method that is been called when the user selects a new item in the list by pressing 'enter' or the device 'accept' key (located in the center of the navigation keys). So just implement that methode and toggle the right item.
| Java: |
import android.app.ListActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.ListView;
public class ExtendedCheckBoxList extends ListActivity {
private ExtendedCheckBoxListAdapter mListAdapter;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
// Build the list adapter
mListAdapter = new ExtendedCheckBoxListAdapter(this);
// Add some items
for( int i = 1; i < 20; i++ )
{
String newItem = "Item " + i;
mListAdapter.addItem( new ExtendedCheckBox(newItem,false));
}
// Bind it to the activity!
setListAdapter(mListAdapter);
}
/**
* If a list item is clicked
* we need to toggle the checkbox too!
*/
@Override
protected void onListItemClick(ListView l, View v, int position, long id) {
// Toggle the checkbox state!
if ( v != null )
{
ExtendedCheckBoxListView CurrentView = (ExtendedCheckBoxListView)v;
if ( CurrentView != null )
{
CurrentView.toggleCheckBoxState();
}
}
super.onListItemClick(l, v, position, id);
}
}
|
5.
Here you got the layout I used and the localized string
main.xml
| XML: |
<?xml version="1.0" encoding="UTF-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<ListView
android:id="@android:id/list"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_weight="1"
android:scrollbars="vertical" />
<TextView
android:id="@android:id/empty"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:text="@string/No_Items"
android:padding="10px" />
</LinearLayout>
|
strings.xml
| XML: |
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="app_name">Extended Check Box List</string>
<string name="No_Items">No Items!</string>
</resources>
|
So we finished, a nice pice of code. Now it's on your own to add more stuff to it. I attached all sources in a eclipse project.
Cheers,
Moss
| Description: |
|
 Download |
| Filename: |
ExtendedCheckBoxList.zip |
| Filesize: |
40.26 KB |
| Downloaded: |
212 Time(s) |
|
|
| Back to top |
|
 |
|
|
 |
ksly Freshman

Joined: 11 Apr 2009 Posts: 3
|
Posted: Mon Apr 13, 2009 2:48 am Post subject: setOnClick |
|
|
Hi,
Thanks for the Tut, It helped me out alot, I cant figure out how to let the main activity know then a list item was selected. How do you do that .
Thanks
|
|
| Back to top |
|
 |
B_Thax Freshman


Joined: 17 Jul 2008 Posts: 9 Location: Palma de Mallorca
|
Posted: Mon Apr 13, 2009 11:13 am Post subject: |
|
|
It's all the magic done by the ListActivity class. Now a got thing would be creating a new child class of list activity that adds some callbacks for all the selecting logic.
I'm creating one but adding more stuff to it, so when I'm finished with it I'll update all.
Cheers
Moss
_________________ Game Programmer at Tragnarion Studios - www.Tragnarion.com |
|
| Back to top |
|
 |
moein_ak Once Poster

Joined: 17 Apr 2009 Posts: 1
|
Posted: Fri Apr 17, 2009 9:14 pm Post subject: |
|
|
thanks for this tutorial
it was really useful for me
|
|
| Back to top |
|
 |
tompalmeras Freshman

Joined: 09 Jun 2009 Posts: 3
|
Posted: Wed Jun 10, 2009 11:13 am Post subject: |
|
|
Thanks for the tut, it was very helpfull too.
Small question however :
I adapted this tuto for my application. When I click on an item using keyboard (calls to onListItemClick() ), all views are (re)generated. May I miss something?
Thanks
Tom
|
|
| Back to top |
|
 |
B_Thax Freshman


Joined: 17 Jul 2008 Posts: 9 Location: Palma de Mallorca
|
Posted: Sun Oct 18, 2009 11:01 am Post subject: |
|
|
Yes that could actually happen. In get view we always generate a new one, this is the easiest way but not the best. You should cache the views, in the last google IO Romain Guy made a quite nice approach on this, just check the videos about the sessions and you'll find out the right why to cache views and not to refresh the whole list.
_________________ Game Programmer at Tragnarion Studios - www.Tragnarion.com |
|
| Back to top |
|
 |
|
|
 |
airswit Once Poster

Joined: 01 Jan 2010 Posts: 1
|
Posted: Fri Jan 01, 2010 5:15 am Post subject: |
|
|
Hi,
I'd like to see two more things added:
1 (most important) : how can I trigger the ListView.isItemChecked() method to return true with this implementation?
2 : Can you outline how to modify this to work with a SimpleCursorAdapter?
Thanks!
|
|
| Back to top |
|
 |
rayman Junior Developer

Joined: 11 Jan 2010 Posts: 10
|
Posted: Fri Jan 15, 2010 12:14 pm Post subject: add custem list item |
|
|
Hi,
I would like to know, if i want to add my own custom list item, with it's own layout,
i had some difficulties to do it, could you explain with some simple example?
thanks,
ray.
|
|
| Back to top |
|
 |
kitty Junior Developer

Joined: 02 Dec 2009 Posts: 21 Location: India
|
Posted: Sat Jan 23, 2010 7:27 am Post subject: Position of the checkbox |
|
|
Hi,
Thanks for the tutorial, it was really helpful to me. I'm using your tutorial in my application, in which i'm listing out the files i.e., instead of items i'm displaying the names of the files existing in the device. The problem with the list is when i click the list item the file should be opened but the onClicklistener of that listview is not working, when i place the checkbox in the list. For that to happen i'm using the checkbox, i'm trying to open the file by capturing click on checkbox in the Listview. But i'm not able to capture the position of the checkbox that was clicked.
My goal is to open the file that was checked or clicked.
Please share your ideas with me
____________________
Regards,
Kitty
|
|
| Back to top |
|
 |
B_Thax Freshman


Joined: 17 Jul 2008 Posts: 9 Location: Palma de Mallorca
|
Posted: Sat Jan 23, 2010 4:44 pm Post subject: |
|
|
You should be able to find the parent of the checkbox that has been checked and than you could look in the list in which position that one is.
A simpler way would be creating a new checkbox class that holds the position within the list for itself, that would be much stabler and quite optimized.
_________________ Game Programmer at Tragnarion Studios - www.Tragnarion.com |
|
| Back to top |
|
 |
kitty Junior Developer

Joined: 02 Dec 2009 Posts: 21 Location: India
|
Posted: Mon Jan 25, 2010 11:21 am Post subject: |
|
|
Hi B_Thax,
Thanks for your reply. I would like to know how to find the parent of the Checkbox??? i'm getting the package path(com.android.filname.xxxx) when i use the getParent method for the Checkbox. How to create a new Checkbox class? Please don't mind if i'm asking some stupid questions because i'm a newbie to android.
If it is possible, please provide me some sample code for writing Checkbox class or for finding the parent of the Checkbox.
_______________
Thanks and regards,
Kitty
|
|
| Back to top |
|
 |
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum You cannot attach files in this forum You can download files in this forum
|
© 2007, Android Development Community
All rights reserved.
Powered by phpBB.
|