具有CheckBox的列表项无法单击

时间:2011-08-04 04:39:48

标签: android listview

我有一个包含CheckBox的列表项,我希望能够单击CheckBox和列表项本身。不幸的是,两者之间似乎存在某种冲突,因为我只能在注释掉CheckBox时单击该项。我好像记得有办法解决这个问题,但目前我找不到它。感谢

编辑:这是一个ListFragment,因此无需调用setOnItemClickListener。

好的,这是列表项的XML。问题是CheckBox,但我想也可以复制一切。

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

9 个答案:

答案 0 :(得分:27)

您需要将此添加到自定义适配器xml文件 android:descendantFocusability =“blocksDescendants”

答案 1 :(得分:22)

将其插入项目行的 根元素 xml文件

android:descendantFocusability="blocksDescendants"

答案 2 :(得分:8)

正如herehere所述,这可能是一个已知问题,也可能是按设计工作的。如果列表项中有任何可点击或可聚焦的项目,则列表项本身不可单击。 Romain Guy says“这是为了支持轨迹球/ dpad导航。”

答案 3 :(得分:6)

这为我做了工作

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

答案 4 :(得分:1)

我用这种方式解决了这个问题。我在适配器中实现了OnClickListener,而不是在Fragment / Activity中实现,它运行良好。现在我可以使用带有复选框的ListView,并且可以单击两者。这是我的代码:

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;
    }

    ...
}

答案 5 :(得分:1)

您是否尝试过设置

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

它对我有用。

答案 6 :(得分:1)

使用     机器人:descendantFocusability =&#34; blocksDescendants&#34; 工作正常

答案 7 :(得分:0)

ok ..创建一个CheckBox实例,如

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

将上面的代码放在onItemClickListener或您正在使用的Adapter中。现在做一个类似的 以下

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

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

        public void onClick(View v) 
        {

        }

    }

执行onClick中的任何功能。

答案 8 :(得分:0)

迟到了,但仍然是所有仍需要它的人的解决方案。

内置机制确实使用:

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

不允许两者,即单击复选框并单击列表项。无论何处单击,复选框都会捕获事件。

但是,如果您使用getView创建自己的ArrayAdapter,那么它可以正常工作:

    @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;
    }

}