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

36 Responses to “Android: Checkable Linear Layout”

  1. Posted by Androidaler

    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.

  2. Posted by Androidaler

    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 *

  3. Posted by Androidaler

    * 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.

  4. Posted by thk

    Strange, could that be a problem with the adapter that you are using? Sounds like you might not be properly inflating your items.

  5. Posted by Androidaler

    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.

  6. Posted by Androidaler

    Auto correct….fail.

  7. Posted by thk

    Indeed lol :)

  8. Posted by Varun

    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?

  9. Posted by Varun

    OMG, commented on a wrong blog entry!..Sorry , my head’s spinning these days.

  10. Posted by thk

    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

  11. Posted by Eik

    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!

  12. Posted by thk

    You are welcome!

  13. Posted by Fabrizio Giudici

    Thanks from me too. You solved me a few headaches.

  14. Posted by PhiBo

    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. ;)

  15. Posted by thk

    No worries, but maybe I should get one :)

  16. Posted by Owen Borseth

    Thank you!! Saved me a ton of time.

  17. Posted by Raul

    Hey man! You saved my day.
    Love from Sweden

  18. Posted by Android: Change ListView Row TextView Color When Checked | BitMote

    [...] As my listview rows are LinearLayouts I need a checkable one, so I took one from tokudu [...]

  19. Posted by Poornima

    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

  20. Posted by happy reader

    Hi,
    Followed your instructions exactly and this worked great! Exactly what I needed!

  21. Posted by ash

    Hey.. this is awesome … i ws stucked in my proj w/o this .. u r an Angel .. :) :) :)

  22. Posted by Infrared Heaters

    :`* I am really thankful to this topic because it really gives great information *`-

  23. Posted by Iren

    Dear Infrared Heaters can you write the whole code, I am some difficulties to understand .
    Please it’s very important for me.

  24. Posted by Martin

    How would you go about using this handy little feature with a listview? How do you reference this layout ?

  25. Posted by Dirk Troutner

    This site is excellent. How has been that produced ?

  26. Posted by vimax

    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

  27. Posted by Denmark Green Card

    I like your post. Good job!

  28. Posted by Vishwa Prakash A

    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?

  29. Posted by Catherine

    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.

  30. Posted by Jules

    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

  31. Posted by Jules

    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

  32. Posted by Jules

    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…

  33. Posted by Steve

    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

  34. Posted by cmh

    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 ?

  35. Posted by cmh

    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
    ……

  36. Posted by Pooja

    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….

Leave a Reply