34

我从 ApiDemos看到了示例com.example.android.apis.view.List11 。在该示例中,每一行都采用视图android.R.simple_list_item_multiple_choice。每个这样的视图都有一个TextView和一个CheckBox

现在我希望每个视图都有 2 TextViews 和 1 CheckBox,有点类似于List3示例。我尝试像这样创建自定义布局文件 row.xml:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    >
    <CheckBox
        android:id="@+id/checkbox"
        android:layout_alignParentRight="true"
        android:layout_width="wrap_content"
        android:layout_height="fill_parent" />
    <TextView
        android:id="@+id/text_name"
        android:textSize="13px"
        android:textStyle="bold"
        android:layout_toLeftOf="@id/checkbox"
        android:layout_alignParentLeft="true"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content" />
    <TextView
        android:id="@+id/text_phone"
        android:textSize="9px"
        android:layout_toLeftOf="@id/checkbox"
        android:layout_below="@id/text_name"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content" /> 
</RelativeLayout>

然后在Activity'sonCreate()中,我确实喜欢这样:

public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    // Query the contacts
    mCursor = getContentResolver().query(Phones.CONTENT_URI, null, null, null, null);
    startManagingCursor(mCursor);

    ListAdapter adapter = new SimpleCursorAdapter(this,
            R.layout.row,
            mCursor, 
            new String[] { Phones.NAME, Phones.NUMBER}, 
            new int[] { R.id.text_name, R.id.text_phone });
    setListAdapter(adapter);
    getListView().setChoiceMode(ListView.CHOICE_MODE_MULTIPLE);
}

结果有点像我想要的,但看起来列表不知道选择了哪个项目。另外,我需要准确地单击CheckBox. 在 List11 示例中,我只需要单击项目行。

那么我需要做什么才能使用我的自定义视图为每一行制作一个多项选择列表?非常感谢。

4

9 回答 9

17

您必须自己RelativeLayout实现Checkable接口并引用CheckBox或引用CheckedTextView(如果是多选模式,则为列表)。

看看这个帖子: http: //www.marvinlabs.com/2010/10/29/custom-listview-ability-check-items/

于 2011-02-17T17:32:28.103 回答
7

Rahul Garg 的答案在第一次加载列表时很好,如果您希望根据模型数据检查某些行,但之后您必须自己处理检查/取消检查事件。

您可以覆盖onListItemCLick()ListActivity选中/取消选中行

@Override
protected void onListItemClick(ListView l, View v, int position, long id) {
    super.onListItemClick(l, v, position, id);
    ViewGroup row = (ViewGroup)v;
 CheckBox check = (CheckBox) row.findViewById(R.id.checkbox);            
    check.toggle();
}

如果这样做,请不要设置ListViewto CHOICE_MODE_MULTIPLE,因为它在调用函数时会产生奇怪的事情。

要检索检查行的列表,您必须自己实现一个方法,调用getCheckItemIds()不起作用ListView

ListView l = getListView();
int count = l.getCount();
for(int i=0; i<count; ++i) {
   ViewGroup row = (ViewGroup)l.getChildAt(i);
   CheckBox check = (Checked) row.findViewById(R.id.ck1);
   if( check.isChecked() ) {
      // do something
   }
}
于 2011-01-19T14:45:26.690 回答
5

解决方案是创建一个实现 Clickable 接口的自定义 View。

public class OneLineCheckableListItem extends LinearLayout implements Checkable {

    public OneLineCheckableListItem(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    private boolean checked;


    @Override
    public boolean isChecked() {
        return checked;
    }

    @Override
    public void setChecked(boolean checked) {
        this.checked = checked; 

        ImageView iv = (ImageView) findViewById(R.id.SelectImageView);
        iv.setImageResource(checked ? R.drawable.button_up : R.drawable.button_down);
    }

    @Override
    public void toggle() {
        this.checked = !this.checked;
    }
}

并使用新的小部件为列表项创建自定义布局。

<?xml version="1.0" encoding="utf-8"?>
<ax.wordster.OneLineCheckableListItem xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:layout_marginBottom="4dp"
    android:background="@drawable/selector_listitem"
    android:orientation="horizontal" >

    <ImageView
        android:id="@+id/SelectImageView"
        android:layout_width="60dp"
        android:layout_height="60dp"
        android:src="@drawable/button_friends_down" />

    <TextView
        android:id="@+id/ItemTextView"
        android:layout_width="fill_parent"
        android:layout_height="60dp"
        android:gravity="center"
        android:text="@string/___"
        android:textAppearance="?android:attr/textAppearanceLarge"
        android:textColor="@color/text_item" />

</ax.wordster.OneLineCheckableListItem>

然后使用上面的布局创建一个新的自定义适配器。

于 2013-02-08T19:48:01.107 回答
5

每个这样的视图都有一个 TextView 和一个 CheckBox。

不,它没有。它有一个CheckedTextView.

那么我需要做什么才能使用我的自定义视图为每一行制作一个多项选择列表?

尝试使CheckBox android:id价值成为"@android:id/text1",看看是否有帮助。这是 Android 用于CheckedTextViewin的 ID simple_list_item_multiple_choice

于 2010-04-16T12:49:22.860 回答
1

我发现这个小代码非常有用:http: //alvinalexander.com/java/jwarehouse/apps-for-android/RingsExtended/src/com/example/android/rings_extended/CheckableRelativeLayout.java.shtml

这是对 @ferdy182 的http://www.marvinlabs.com/2010/10/29/custom-listview-ability-check-items/内容的一个很好的补充。

于 2014-12-22T10:33:53.733 回答
1

如何让自定义布局作为自定义复选框工作的简单示例:

private class FriendsAdapter extends ArrayAdapter<WordsterUser> {
    private Context context;

    public FriendsAdapter(Context context) {
        super(context, R.layout.listitem_oneline);

        this.context = context;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        final int pos = position;

        LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);

        View rv = inflater.inflate(R.layout.listitem_oneline, parent, false);
        rv.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                boolean checked = friendsListView.isItemChecked(pos); 
                friendsListView.setItemChecked(pos, !checked);
            }
        });

        WordsterUser u = getItem(position);

        TextView itw = (TextView) rv.findViewById(R.id.ItemTextView);
        itw.setText(u.userName + " (" + u.loginName + ")");

        ImageView iv = (ImageView) rv.findViewById(R.id.SelectButton);

        if (friendsListView.isItemChecked(position)) {
            iv.setImageResource(R.drawable.downbutton);
        } else {
            iv.setImageResource(R.drawable.upbutton);
        }

        return rv;
    }
}
于 2013-02-08T17:41:21.640 回答
1

可以通过一些技巧

在您的 ListActivtyClass 方法中

protected void onListItemClick(ListView l, View v, int position, long id) {
//just set
<your_model>.setSelected(true);
}

现在在您的自定义适配器中

public View getView(int position, View convertView, ViewGroup parent) {
        if (convertView == null) {
            LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            convertView = inflater.inflate(textViewResourceId, parent, false);
        }       
        if (<your_model>.isSelected()) {
            convertView.setBackgroundColor(Color.BLUE);
        } else {
            convertView.setBackgroundColor(Color.BLACK);
        }
        return convertView;
    }

这样,您可以在列表中选择项目时自定义适配器中的视图。

于 2010-11-22T17:05:48.567 回答
0

我想确认普里塔姆的回答是正确的。您需要onClickListener在每个列表的项目上都有一个(在适配器的 中定义它getView())。

您可以为每个项目创建一个新onClickListener()项目,或者让适配器实现onClickListener()- 在这种情况下,必须标记项目以便侦听器知道它正在操作哪个项目。

依赖列表onItemClickListener()- 正如有人在另一个线程中建议的那样 - 将不起作用,因为CheckBox它将拦截点击事件,因此列表不会得到它。

最后是@Rahul 和 JVitella:

情况是CheckBox列表项上的 必须独立于列表项本身是可单击和可检查的。因此,解决方案就像我上面描述的那样。

于 2011-02-09T15:51:34.497 回答
0

得到了解决方案...您可以通过在适配器本身中为每个视图添加侦听器来获得对视图的点击(如自定义行布局中的复选框),同时在 getView() 中返回转换后的视图。如果您打算获取任何列表特定信息,您可能必须传递列表对象的引用。像行ID。

于 2010-12-20T13:35:11.483 回答