Shawn Lauzon
Shawn Lauzon

Reputation: 6282

List item with CheckBox not clickable

I have a list item which contains a CheckBox, and I want to be able to click on the CheckBox and on the list item itself. Unfortunately, there seems to be some sort of conflict between the two, as I can only click on the item when I comment out the CheckBox. It seems like I recall there was a way to fix this, but I can't find it at the moment. Thanks

EDIT: This is with a ListFragment, so there's no need to call setOnItemClickListener.

OK, here's the XML for the list item. The problem is the CheckBox, but I figured might as well copy everything.

<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/list_item_survey"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    style="@style/SimpleListItem">
    <TextView
        android:id="@+id/survey_title"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        style="@style/ListItemTitle" />
    <TextView
        android:id="@+id/survey_date"
        android:layout_below="@id/survey_title"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        style="@style/ListItemSubtitle" />
    <TextView
        android:id="@+id/survey_completed"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentRight="true"
        android:layout_below="@id/survey_title"
        android:textColor="@color/accent_1"
        android:text="@string/survey_completed"
        style="@style/ListItemSubtitle" />
    <CheckBox
        android:id="@+id/survey_did_not_attend"
        android:layout_below="@id/survey_date"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/survey_did_not_attend"
        android:focusable="false"
        style="@style/ListItemSubtitle" />
 </RelativeLayout>

Upvotes: 23

Views: 19940

Answers (9)

Kevin ABRIOUX
Kevin ABRIOUX

Reputation: 17695

This did the work for me

<CheckBox
...                
android:focusable="false"
android:clickable="false"
android:focusableInTouchMode="false" />

Upvotes: 6

sarankumar
sarankumar

Reputation: 229

insert this into the root element of the item row xml file

android:descendantFocusability="blocksDescendants"

Upvotes: 23

Suresh kumar
Suresh kumar

Reputation: 799

by using android:descendantFocusability="blocksDescendants" its working fine

Upvotes: 1

logRish
logRish

Reputation: 11

Have you tried setting

android:focusable="false"
android:focusableInTouchMode="false"

?

It worked for me.

Upvotes: 1

Sunil
Sunil

Reputation: 864

You need to add this to your custom adapter xml file android:descendantFocusability="blocksDescendants"

Upvotes: 28

user387184
user387184

Reputation: 11053

Late, but nevertheless a solution for all those who still need it.

It is true that the built-in mechanism using:

final ArrayAdapter<String> adapter = new ArrayAdapter<String>(
    getActivity(),
    android.R.layout.simple_list_item_multiple_choice, lst);

does not allow both, ie click on the checkbox AND click on the list item. Wherever one clicks, the checkbox catches the event.

However, if you create your own ArrayAdapter with getView like this, then it works fine:

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
    View v = convertView;
    if (v == null) {
        LayoutInflater vi = (LayoutInflater) mContext
            .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        v = vi.inflate(R.layout.list_item_ecu_fehler, null);
    }

    v.setFocusable(true);
    v.setOnClickListener(new OnClickListener() {
        @Override
        public void onClick(View v) {
        if (DEBUG)
            Log.i(this.getClass().getSimpleName(),
                " ->>"
                    + Thread.currentThread().getStackTrace()[2]
                        .getMethodName());
        }
    });

            CheckBox selectedForClearingCB = (CheckBox) v
            .findViewById(R.id.checkBox);


        if (selectedForClearingCB != null) {
        selectedForClearingCB.setTag(position); //so we know position in the list       selectedForClearingCB.setChecked(true);
        selectedForClearingCB.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {

            if (((CheckBox) v).isChecked()) {
                if (DEBUG)
                Log.i(this.getClass().getSimpleName(),
                    " -> CB checked: "
                        + Integer.toString((Integer) v
                            .getTag()));

            }

            }
        });
        }
    }
    return v;
    }

}

Upvotes: 0

petrnohejl
petrnohejl

Reputation: 7759

I solved the problem this way. I implemented OnClickListener inside the Adapter and not in the Fragment/Activity and it works well. Now I can use ListView with checkboxes and can click on both. Here is my code:

public class MyFragment extends Fragment
{
    ...

    private void setView()
    {
        ListView listView = (ListView) mRootView.findViewById(R.id.listview);
        mItems = DatabaseManager.getManager().getItems();

        // create adapter
        if(listView.getAdapter()==null)
        {
            MyAdapter adapter = new MyAdapter(this, mItems);
            try
            {
                listView.setAdapter(adapter);
            }
            catch(Exception e)
            {
                e.printStackTrace();
                return;
            }
        } 
        else 
        {
            try
            {
                ((MyAdapter) listView.getAdapter()).refill(mItems);
                BaseAdapter adapter = (BaseAdapter) listView.getAdapter();
                listView.requestLayout();
                adapter.notifyDataSetChanged();
            }
            catch(Exception e)
            {
                e.printStackTrace();
                return;
            }
        }

        // handle listview item click
        listView.setClickable(true);
        // listView.setOnItemClickListener(...); // this method does not work in our case, so we can handle that in adapter
    }

    ...
}


public class MyAdapter extends BaseAdapter
{
    ...

    @Override
    public View getView(final int position, View convertView, ViewGroup parent)
    {
        View view = convertView;
        if (view == null) 
        {
            LayoutInflater inflater = (LayoutInflater) mFragment.getActivity().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            view = inflater.inflate(R.layout.listview_item, null);
        }

        ...

        // handle listview item click
        // this method works pretty well also with checkboxes
        view.setOnClickListener(new OnClickListener()
        {
            @Override
            public void onClick(View v)
            {
                // do something here
                // for communication with Fragment/Activity, you can use your own listener
            }
        });

        return view;
    }

    ...
}

Upvotes: 1

Shawn Lauzon
Shawn Lauzon

Reputation: 6282

As described here and here, this is either a known problem or works as designed. If you have any clickable or focusable items in a list item, the list item itself cannot be clickable. Romain Guy says "This is working as intended to support trackball/dpad navigation."

Upvotes: 8

Balban
Balban

Reputation: 736

ok.. Make a CheckBox instance Like

CheckBox check;
check = (CheckBox) myView.findViewById(R.id.check);
check.setOnClickListener(new CheckBoxSelect(position));

put above code in onItemClickListener or in Adapter you are using. now make a class like below

private class CheckBoxSelect implements OnClickListener 
    {
        int pos;
        String str;

        public CheckBoxSelect(int position) 
        {
            pos = position;
        }

        public void onClick(View v) 
        {

        }

    }

perform any functionality in onClick .

Upvotes: 0

Related Questions