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

发布于 2024-08-29 14:43:41 字数 2205 浏览 10 评论 0原文

我已经看到来自 ApiDemos 的示例 com.example.android.apis.view.List11 。在该示例中,每一行都采用视图 android.R.simple_list_item_multiple_choice。每个此类视图都有一个 TextView 和一个 CheckBox

现在我希望每个视图都有 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>

然后在 ActivityonCreate() 中,我确实喜欢这样:

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示例中,我只需要单击项目行。

那么我需要做什么来为每行创建一个带有自定义视图的多项选择列表呢?非常感谢。

I've seen example com.example.android.apis.view.List11 from ApiDemos. In that example, each row takes the view android.R.simple_list_item_multiple_choice. Each such view has a TextView and a CheckBox.

Now I want each view to have 2 TextViews and 1 CheckBox, somewhat similar to the List3 example. I tried creating a custom layout file row.xml like this:

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

Then in Activity's onCreate(), I do like this:

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

The result kind of looks like what I want, but it looks like the list doesn't know which item of it is selected. Also, I need to click exactly on the CheckBox. In the List11 example, I only need to click on the item row.

So what do I need to do to make a multiple choice list with my custom view for each row? Many thanks.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(9

风启觞 2024-09-05 14:43:41

您必须创建自己的 RelativeLayout 来实现 Checkable 接口,并引用 CheckBoxCheckedTextView > (如果是多项选择模式,则为列表)。

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

You have to make your own RelativeLayout that implements the Checkable interface and have a reference to the CheckBox or to the CheckedTextView (or a list if it's multiple choice mode).

Look at this post:
http://www.marvinlabs.com/2010/10/29/custom-listview-ability-check-items/

著墨染雨君画夕 2024-09-05 14:43:41

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

您可以覆盖 ListActivityonListItemCLick() 来检查/取消选中行

@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,因为调用函数时会产生奇怪的结果。

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

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

The answer of Rahul Garg is good for the first time the list is loaded, if you want some rows to be checked depending on the model data, but after that you have to handle the check/uncheck events by yourself.

You can override the onListItemCLick() of the ListActivity to check/uncheck the rows

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

If you do so, do not set the ListView to CHOICE_MODE_MULTIPLE, because it makes strange things when calling the function.

To retrieve the list of checked rows, you have to implement a method yourself, calling getCheckItemIds() on the ListView does not work:

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
   }
}
一口甜 2024-09-05 14:43:41

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

不,事实并非如此。它有一个CheckedTextView

那么我需要做什么来制作一个
具有我的自定义的多项选择列表
查看每一行?

尝试将 CheckBox android:id 值设置为 "@android:id/text1" 并查看是否有帮助。这是 Android 在 simple_list_item_multiple_choice 中用于 CheckedTextView 的 ID。

Each such view has a TextView and a
CheckBox.

No, it doesn't. It has a CheckedTextView.

So what do I need to do to make a
multiple choice list with my custom
view for each row?

Try making the CheckBox android:id value be "@android:id/text1" and see if that helps. That is the ID used by Android for the CheckedTextView in simple_list_item_multiple_choice.

眼眸里的快感 2024-09-05 14:43:41

解决方案是创建一个实现 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>

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

The solution is to create a custom View that implements the Clickable interface.

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

And create a custom layout for the list items using the new widget.

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

Then create a new custom Adapter using the layout above.

情何以堪。 2024-09-05 14:43:41

现在可以通过

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

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

It is possible by some trick

in your ListActivtyClass in method

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

now in you custom Adapter

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

this way you can customize the view in adapter when the item is selected in the list.

千里故人稀 2024-09-05 14:43:41

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

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

Simple example how to get a custom layout to work as custom checkbox:

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;
    }
}
一个人练习一个人 2024-09-05 14:43:41

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

Got the solution ... You can get the clicks on the views (like checkboxes in custom layouts of row) by adding listener to each of them in the adapter itself while you return the converted view in getView(). You may possibly have to pass a reference of list object if you intent to get any list specific info. like row id.

爱你是孤单的心事 2024-09-05 14:43:41

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

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

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

最后@Rahul 和JVitella:

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

I want to confirm that the Pritam's answer is correct. You need an onClickListener on each list's item (define it in the adapter's getView()).

You can create a new onClickListener() for each item, or have the adapter implement onClickListener() - in this case the items must be tagged for the listener to know, which item it is operating on.

Relying on the list onItemClickListener() - as someone advised in another thread - will not work as the CheckBox will intercept the click event so the list will not get it.

And finally @Rahul and JVitella:

The situation is that the CheckBox on a list item must be clickable and checkable independently from the list item itself. Therefore the solution is as I just described above.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文