A common thing you might want to do, when you developing an Android app, is to have a ListView of checkable items. For instance, you might want to have a functionality in your app to share something with a bunch of people, who you would like to select from a list of contacts. For common choice for this task is to use a CheckedTextView and the android:choiceMode parameter of the ListView. This extension of a regular TextView has a check box on the right, so that it can be selected.
However, there is a limitation here. CheckedTextView has to be the root element of the layout that you use for your items. So if you wish to display multiple things (user name and email) for each item by using a LinearLayout, you are out of luck. The reason for this limitation is that he root item must implement the Checkable interface and the LinearLayout doesn’t implement it.
The solution here is to…
…override LinearLayout to implement the required interface. I present to you CheckableLinearLayout. Upon inflation it searches through its children for the CheckedTextView, and then forwards any calls required by the Checkable interfaces to that component:
Now, we can use that component in the layout file for our list items:
Make sure you set in your ListView‘s XML: android:choiceMode=”multipleChoice”.
This class is now a part of my Android library Begemot.
Follow me @tokudu
June 7th, 2010 at 5:16 pm
Thanks for the class example.
However, I’m still running into an issue that I have only seen mentioned a couple times in forums or other threads. And that is that I can only tick (read: check) one checkbox even though I’ve set the choice mode to muliple. And more weird is that if I scroll through my ListView’s files I see checkboxes ticked exactly so many checkboxes apart!
Can you please shed some light on what is happening, how I can fix it? I’ve really tried to solve this myself for about three days now.
Here is the code for my (ListView) row.xml:
Plus, I’ve tried different variations of:
android:focusable=”false”
android:clickable=”true”
android:checked=”false”‘
Thanks for any help you can, may offer.
June 7th, 2010 at 5:18 pm
LinearLayout xmlns:android=”http://schemas.android.com/apk/res/android”
android:id=”@+id/LinearLayout01″
android:layout_width=”fill_parent”
android:layout_height=”wrap_content”
>
ListLayout
* some angle brackets removed to get this to post *
June 7th, 2010 at 5:19 pm
* guess it’s not going to let me paste in my code, I’m sure you get the idea *
It’s Imageview, TextView, TextView, CheckedTextView, from top to bottom wrapped in a LinearLayout.
June 8th, 2010 at 8:54 pm
Strange, could that be a problem with the adapter that you are using? Sounds like you might not be properly inflating your items.
June 9th, 2010 at 12:28 pm
Okay, I’ll double check that, thanks.
I did get it to work but only if the user clicks the list items and not the cheekbones themselves.
June 9th, 2010 at 12:29 pm
Auto correct….fail.
June 9th, 2010 at 2:10 pm
Indeed lol
June 17th, 2010 at 3:17 am
Sir,
The blog entry was extremely helpful to get started with Push notifications.
I spent some time looking into the basic function calls to push messages via the IBM really small broker.
I have a query.How did you make the ‘push messaging’ localized to a specific device id?..The publish function for the client has only four parameters namely
Topic,payload,qos and the retained flag i.e.:
“publish(java.lang.String thisTopic, byte[] thisMessage, int thisQoS, boolean retained)”
Since the source of the IBM broker is not available , how is the default broadcasting of the broker stopped and ability to push messages to a particular device with a specific device id can be implemented?
June 17th, 2010 at 3:20 am
OMG, commented on a wrong blog entry!..Sorry , my head’s spinning these days.
June 18th, 2010 at 11:10 am
Lol, it’s alright. Have a look in my code, but basically I embed the device ID as a part of the message topic. Good luck
August 12th, 2010 at 4:36 pm
Hey i just want to say thank you!!! I searched the whole Web, because i implemented a custom Spinner View and its working, but due to i’m using multiple TextViews in my Spinner DropDown Items i have to use a LinearLayout and guess what, the Checked State doens’t working. But you clearly described the problem and your solution works without any modifications.
Again, thank you and greetings from Germany!
August 16th, 2010 at 10:55 pm
You are welcome!
August 25th, 2010 at 12:13 pm
Thanks from me too. You solved me a few headaches.
September 2nd, 2010 at 2:57 am
Wow, you have no idea of how much time I spent on searching for a solution like this. Thanks a lot. If you had a Flattr button, I’d click it.
September 19th, 2010 at 7:44 pm
No worries, but maybe I should get one
October 8th, 2010 at 9:53 am
Thank you!! Saved me a ton of time.
November 2nd, 2010 at 1:28 am
Hey man! You saved my day.
Love from Sweden
December 28th, 2010 at 4:01 am
[...] As my listview rows are LinearLayouts I need a checkable one, so I took one from tokudu [...]
January 12th, 2011 at 6:34 am
Hi,
I am new to android, i want to embed a checkbox inside a spinner control, with your example i got some idea but am having problem in implement your concept.
If you have any example code, please mail me..
Thanks in advance
January 17th, 2011 at 3:14 pm
Hi,
Followed your instructions exactly and this worked great! Exactly what I needed!
January 24th, 2011 at 12:09 am
Hey.. this is awesome … i ws stucked in my proj w/o this .. u r an Angel ..
January 29th, 2011 at 11:56 pm
:`* I am really thankful to this topic because it really gives great information *`-
January 30th, 2011 at 12:40 pm
Dear Infrared Heaters can you write the whole code, I am some difficulties to understand .
Please it’s very important for me.
July 3rd, 2011 at 2:41 am
How would you go about using this handy little feature with a listview? How do you reference this layout ?
August 1st, 2011 at 1:17 pm
This site is excellent. How has been that produced ?
August 20th, 2011 at 6:23 pm
This is a smart blog. I mean it. You have so much knowledge about this issue, and so much passion. You also know how to make people rally behind it, obviously from the responses. Youve got a design here thats not too flashy, but makes a statement as big as what youre saying. Great job, indeed.
xyxytodwhy.2011
August 30th, 2011 at 7:16 am
I like your post. Good job!
September 8th, 2011 at 5:41 pm
Very good post. But I want the CheckedTextView to be checked only when that portion of the view is clicked and I want the onListItemclick(l, v, pos, id) to be called whenever the rest of the portion in the view (i.e any other text view) is clicked. How can I achieve this?
October 18th, 2011 at 2:56 am
Hi:
Im using ur example, and it works great.
one question, since i need to implement a button on the screen, when click, all the item in the list must be checked.
I did not get the way to implement this, i am thinking sth like to overwriter one method to achive this, but no idea so far.
Could you please give me a hint on this?
Thank you very much.
December 17th, 2011 at 11:57 pm
OK… I assume other people got this working so I must be really stupid or something. I’m using a class very similar to yours (see code posted below), with a ListView with android:choiceMode=”singleChoice”. The only problem is, when I click items, nothing happens. No log entries are produced, which means neither setCheck() nor toggle() on my layout is being called. Any ideas what might be happening?
Layout class (edited to pass html filtering, should be obvious how to change it back…):
public class CheckableLinearLayout extends LinearLayout implements Checkable {
public CheckableLinearLayout(Context context) {
super(context);
}
public CheckableLinearLayout(Context context, AttributeSet attrs) {
super(context, attrs);
}
public boolean isChecked() {
return findCheckableView().isChecked ();
}
public void setChecked(boolean arg0) {
findCheckableView().setChecked (arg0);
Log.i(“”+this, “Check state set to: ” + arg0);
}
public void toggle() {
findCheckableView().toggle ();
Log.i(“”+this, “Toggled”);
}
private Checkable findCheckableView() {
for (int i = 0; i (less than) getChildCount(); i++)
{
if (getChildAt(i) instanceof Checkable) {
Log.i(“”+this, “Checkable view found @ ” + i);
return (Checkable) getChildAt(i);
}
}
throw new IllegalArgumentException (“CheckableLinearLayout: must have at least one checkable child view”);
}
}
List item layout (with less than/greater than symbols removed):
org.dsf.novelkit.CheckableLinearLayout xmlns:android=”http://schemas.android.com/apk/res/android”
android:layout_width=”fill_parent”
android:layout_height=”fill_parent”
android:layout_marginBottom=”2px”
android:layout_marginTop=”2px”
android:clickable=”true”
android:orientation=”horizontal”
RadioButton
android:id=”@+id/radioButton1″
android:layout_width=”wrap_content”
android:layout_height=”wrap_content”
android:layout_marginRight=”10dp”
android:text=”@string/emptyString” /
TextView
android:id=”@+id/txtTitle”
android:layout_width=”fill_parent”
android:layout_height=”wrap_content”
android:text=”@string/title” /
/org.dsf.novelkit.CheckableLinearLayout
December 18th, 2011 at 12:01 am
Also relevant, the ListView declaration in the layout for the activity:
ListView
android:id=”@+id/lvNovels”
android:layout_width=”fill_parent”
android:layout_height=”fill_parent”
android:layout_weight=”1″
android:choiceMode=”singleChoice”
!– Preview: listitem=@layout/novellistitem –
/ListView
December 18th, 2011 at 1:44 am
OK… for some reason I don’t *entirely* understand, the checkable view has to be a CheckedTextView. RadioButton doesn’t work, despite the fact that it implements exactly the same interfaces…
February 22nd, 2012 at 4:08 pm
I have implemented your code, it works very well except checked items do not get “unchecked” if you click an already selected item. The checkbox shows the unchecked icon fine, its just when I loop through the checked items with getCheckedItemPositions() the checked then unchecked items still show up. I hope I have explained myself clearly!
Thanks,
Steve
March 14th, 2012 at 7:07 pm
How about use a radio button to replace of the checked box ?
If yes, how to do it and how to get the position/content of the listview that the radio button enabled ?
March 14th, 2012 at 11:44 pm
Dear Anton,
I am new to Android development and looking for a way, couple days, to show mutiple items accompany with a radiobutton/checked marked on a ListView. Fortunity, it seems there is a solution provided here.
I tried to implement it and did a test on my applicaiton. However, there was errors prompted while starting the activity. A java code,2 xml files and error message are posted below. If you don’t mind, could you help me to take a view ?
Thanks a lot for the help !
—Java main program—
MultipleItemsListView.java
package list.view;
import android.app.Activity;
import android.os.Bundle;
import android.widget.ListView;
import android.widget.SimpleAdapter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
public class MultipleItemsListView extends Activity
{
private ListView mListView01;
private SimpleAdapter mSimpleAdapter;
private List allTxt1;
private List allTxt2;
private List allTxt3;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
mListView01 = (ListView)this.findViewById(R.id.listView1);
updateListView();
}
private void updateListView()
{
allTxt1 = new ArrayList();
allTxt2 = new ArrayList();
allTxt3 = new ArrayList();
for (int i = 0 ; i0)
{
ArrayList<HashMap> mylist = new ArrayList<HashMap>();
HashMap map;
for (int i = 0; i< allTxt1.size(); i++)
{
map = new HashMap();
map.put(“txt1″, allTxt1.get(i));
map.put(“txt2″, allTxt2.get(i));
map.put(“txt3″, allTxt3.get(i));
mylist.add(map);
}
mSimpleAdapter = new SimpleAdapter
(
this, mylist, R.layout.items_list ,
new String[] {“txt1″, “txt2″, “txt3″},
new int[] {R.id.textView1, R.id.textView2 , R.id.textView3 }
);
mListView01.setItemsCanFocus(true);
mListView01.setChoiceMode(ListView.CHOICE_MODE_SINGLE);
mListView01.setAdapter(mSimpleAdapter);
}
}
}
—-2 XML Layout files—–
main.xml
items_list.xml
Error Message: (Please see the line 4 for for the error caused)
……
3-15 06:00:31.218: D/AndroidRuntime(1038): Shutting down VM
03-15 06:00:31.228: W/dalvikvm(1038): threadid=1: thread exiting with uncaught exception (group=0×40015560)
03-15 06:00:31.268: E/AndroidRuntime(1038): FATAL EXCEPTION: main
03-15 06:00:31.268: E/AndroidRuntime(1038): android.view.InflateException: Binary XML file line #2: Error inflating class CheckableLinearLayout
03-15 06:00:31.268: E/AndroidRuntime(1038): at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:581)
03-15 06:00:31.268: E/AndroidRuntime(1038): at android.view.LayoutInflater.inflate(LayoutInflater.java:386)
03-15 06:00:31.268: E/AndroidRuntime(1038): at android.view.LayoutInflater.inflate(LayoutInflater.java:320)
03-15 06:00:31.268: E/AndroidRuntime(1038): at android.widget.SimpleAdapter.createViewFromResource(SimpleAdapter.java:121)
03-15
……
May 10th, 2012 at 6:10 am
hi
I have buttons that generate dynamically in linear layout….
when i click on one button , related to that, that particular column,row should be High lighted…..
Please reply to my query thanks in advance….