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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2652109/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-20 06:47:05  来源:igfitidea点击:

Multiple choice list with custom view?

androidlistviewuser-interfacecustom-view

提问by Phil

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

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

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

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

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

然后在Activity's 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);
}

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.

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

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

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

回答by Fernando Gallego

You have to make your own RelativeLayoutthat implements the Checkableinterface and have a reference to the CheckBoxor to the CheckedTextView(or a list if it's multiple choice mode).

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

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

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

回答by JVitela

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.

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

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

您可以覆盖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();
}

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

如果这样做,请不要将 设置ListViewCHOICE_MODE_MULTIPLE,因为在调用该函数时会出现奇怪的情况。

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

要检索检查行的名单,你必须自己实现的方法,呼吁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
   }
}

回答by CommonsWare

Each such view has a TextView and a CheckBox.

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

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

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

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

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

Try making the CheckBoxandroid:idvalue be "@android:id/text1"and see if that helps. That is the ID used by Android for the CheckedTextViewin simple_list_item_multiple_choice.

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

回答by Adorjan Princz

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

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

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.

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

回答by Rahul Garg

It is possible by some trick

这是可能的一些技巧

in your ListActivtyClass in method

在你的 ListActivtyClass 方法中

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.

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

回答by Adorjan Princz

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

回答by Yar

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

我想确认 Pritam 的回答是正确的。您需要onClickListener在每个列表的项目上都有一个(在适配器的 中定义它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.

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

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

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

And finally @Rahul and JVitella:

最后@Rahul 和 JVitella:

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

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

回答by Pritam

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.

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