自定义视图的多选列表?
我见过来自ApiDemos的示例com.example.android.apis.view.List11 。 在这个例子中,每一行都是android.R.simple_list_item_multiple_choice视图。 每个这样的视图都有一个TextView
和一个CheckBox
。
现在我希望每个视图都有2个TextView
和1个CheckBox
,这和List3的例子有点类似。 我试图创build一个自定义的布局文件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
的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); }
结果类似看起来像我想要的,但它看起来像列表不知道select哪个项目。 另外,我需要点击确切的CheckBox
。 在List11的例子中,我只需要点击项目行。
那么,我需要做什么来做出与我的自定义视图为每一行多选列表? 非常感谢。
你必须使自己的RelativeLayout
实现Checkable
接口,并引用CheckBox
或CheckedTextView
(或者是一个列表,如果它是多选模式)。
看看这个post: http : //www.marvinlabs.com/2010/10/29/custom-listview-ability-check-items/
Rahul Garg的答案是第一次加载列表,如果你想要根据模型数据检查一些行,但是之后你必须自己处理check / uncheck事件。
您可以重写onListItemCLick()
来检查/取消选中行
@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 } }
每个这样的视图都有一个TextView和一个CheckBox。
不,不。 它有一个CheckedTextView
。
那么,我需要做什么来做出与我的自定义视图为每一行多选列表?
尝试使CheckBox
android:id
值为"@android:id/text1"
,看看是否有帮助。 这是Android用于CheckedTextView
中的simple_list_item_multiple_choice
的ID。
解决scheme是创build一个实现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; } }
并使用新的小部件为列表项目创build自定义布局。
<?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>
然后使用上面的布局创build一个新的自定义适配器。
这是可能的一些伎俩
在你的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; }
这样,您可以在列表中select项目时自定义适配器中的视图。
简单的例子如何获得自定义布局作为自定义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; } }
我发现这个小代码非常有用: 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/内容的一个很好的补充。;
得到的解决scheme…您可以通过在适配器本身中添加侦听器中的每一个,而您在getView()中返回转换的视图时,获得对视图的点击(如行的自定义布局中的checkbox)。 如果您打算获取任何列表特定信息,您可能必须传递列表对象的引用。 像行ID。
我想确认Pritam的答案是正确的。 您需要在每个列表项目上使用getView()
在适配器的getView()
定义它)。
您可以为每个项目创build一个新的onClickListener()
,或者让适配器实现onClickListener()
– 在这种情况下,项目必须标记为让侦听器知道它正在操作哪个项目。
依赖于列表onItemClickListener()
– 在另一个线程中build议的人 – 将不会工作,因为CheckBox
将拦截click事件,所以列表不会得到它。
最后@Rahul和JVitella:
情况是列表项上的CheckBox
必须是可单击的,并且可以从列表项本身单独检查。 因此,解决scheme如上所述。