具有自定义视图的多选列表?

时间:2010-04-16 10:17:54

标签: android listview user-interface custom-view

我见过ApiDemos的示例 com.example.android.apis.view.List11 。在该示例中,每一行都采用视图 android.R.simple_list_item_multiple_choice 。每个此类视图都有TextViewCheckBox

现在我希望每个视图都有2个TextView和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的{​​{1}}中,我确实喜欢这个:

onCreate()

结果看起来像我想要的,但看起来列表不知道选择了哪个项目。另外,我需要完全点击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); } 。在List11示例中,我只需要单击项目行。

那么我需要做什么才能为每行创建一个包含自定义视图的多选列表?非常感谢。

9 个答案:

答案 0 :(得分:17)

您必须制作自己的RelativeLayout来实现Checkable界面,并引用CheckBoxCheckedTextView(如果它是多项选择的列表)模式)。

看看这篇文章: http://www.marvinlabs.com/2010/10/29/custom-listview-ability-check-items/

答案 1 :(得分:7)

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

您可以覆盖onListItemCLick()的{​​{1}}来检查/取消选中行

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(); } 设置为ListView,因为调用该函数时会出现奇怪的事情。

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

ListView

答案 2 :(得分:5)

  

每个这样的视图都有一个TextView和一个   复选框。

不,它没有。它有一个CheckedTextView

  

那么我需要做些什么呢?   我的自定义多选列表   查看每一行?

尝试将CheckBox android:id值设为"@android:id/text1",看看是否有帮助。这是Android用于CheckedTextViewsimple_list_item_multiple_choice的ID。

答案 3 :(得分: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>

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

答案 4 :(得分: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;
    }

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

答案 5 :(得分: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;
    }
}

答案 6 :(得分:1)

答案 7 :(得分:0)

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

答案 8 :(得分:0)

我想确认Pritam的答案是正确的。您需要在每个列表的项目上onClickListener(在适配器的getView()中定义它)。

您可以为每个项目创建一个新的onClickListener(),或者让适配器实现onClickListener() - 在这种情况下,必须标记项目以便监听器知道它正在运行的项目。< / p>

依赖于列表onItemClickListener() - 在另一个线程中建议的人 - 将无法正常工作,因为CheckBox将拦截点击事件,因此列表将无法获取。

最后@Rahul和JVitella:

情况是列表项上的CheckBox必须是可单独检查的,并且可以独立于列表项本身进行检查。因此,解决方案正如我刚才所述。