Izy*_*orr 17 android listview checkedtextview
我有一个ListView,显示2种项目.其中一种包含CheckedTextView.作为一个适配器,我正在使用自定义适配器扩展ArrayAdapter,其数据结构包含有关内部已检查/未检查状态的信息.
有些项目被标记为已选中(在我的数据结构中),所以我当然希望在创建ListView时标记复选框.我尝试使用CheckedTextView的setChecked()方法在适配器中的getView()方法上执行此操作,但它不起作用.我发现它应该在ListView级别上使用setItemChecked()来完成它并且它确实有效,但它对我来说没有意义,因为为了使它工作,我必须循环活动的onCreate()中的所有项目调用setItemChecked()对于那些被选中 项目列表可能很长,只选择了少数项目,这是浪费.
为什么在getView()中调用setChecked()不起作用?有没有更好的方法(我是一个Android新手).
下面是我检查的项目布局和适配器.
布局:
<?xml version="1.0" encoding="utf-8"?>
<CheckedTextView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@android:id/text1"
android:layout_width="fill_parent"
android:layout_height="?android:attr/listPreferredItemHeight"
android:gravity="center_vertical"
android:textAppearance="@style/listViewItemText"
android:checkMark="?android:attr/listChoiceIndicatorMultiple"
android:paddingLeft="6dp"
android:paddingRight="6dp"
/>
Run Code Online (Sandbox Code Playgroud)
适配器:
package com.melog.re.droid.search;
import java.util.ArrayList;
import java.util.List;
import android.content.Context;
import android.os.Parcel;
import android.os.Parcelable;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.CheckedTextView;
import android.widget.TextView;
import com.melog.re.droid.core.R;
import com.melog.re.droid.search.MultiCriterionValue.MultiCriterionSingleValue;
import com.melog.re.droid.search.MultiListAdapter.MultiChoiceItem;
public class MultiListAdapter extends ArrayAdapter<MultiChoiceItem> {
private static final int VIEW_TYPES_COUNT = 2;
public static final int VIEW_TYPE_GROUP = 0;
public static final int VIEW_TYPE_ITEM = 1;
private LayoutInflater mInflater;
public MultiListAdapter(Context context, int textViewResourceId, List<MultiChoiceItem> objects) {
super(context, textViewResourceId, objects);
mInflater = LayoutInflater.from(context);
}
@Override
public int getItemViewType(int position) {
MultiChoiceItem item = getItem(position);
return (item.children.size() == 0) ? VIEW_TYPE_ITEM : VIEW_TYPE_GROUP;
}
@Override
public int getViewTypeCount() {
return VIEW_TYPES_COUNT;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
// TODO: optymalizacja ViewHolder
MultiChoiceItem item = getItem(position);
int viewType = getItemViewType(position);
switch (viewType) {
case VIEW_TYPE_GROUP:
if (convertView == null) {
convertView = mInflater.inflate(R.layout.multi_choice_group_item, parent, false);
}
TextView groupLabel = (TextView) convertView.findViewById(android.R.id.text1);
groupLabel.setText(item.toString());
break;
case VIEW_TYPE_ITEM:
if (convertView == null) {
convertView = mInflater.inflate(R.layout.multi_choice_child_item, parent, false);
}
CheckedTextView itemLabel = (CheckedTextView) convertView.findViewById(android.R.id.text1);
itemLabel.setText(item.toString());
itemLabel.setChecked(item.selected);
break;
}
return convertView;
}
public static class MultiChoiceItem implements Parcelable {
public static final int CONTENTS_DESCR = 1;
public String label;
public String value;
public boolean selected = false;
public ArrayList<MultiChoiceItem> children = new ArrayList<MultiChoiceItem>();
public MultiChoiceItem(String l, String v, boolean sel) {
label = l;
value = v;
selected = sel;
}
public MultiChoiceItem(MultiCriterionSingleValue v) {
label = v.toString();
value = v.value;
}
public MultiChoiceItem(Parcel in) {
label = in.readString();
value = in.readString();
selected = (in.readInt() == 1);
}
@Override
public String toString() {
return label;
}
@Override
public int describeContents() {
return CONTENTS_DESCR;
}
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(label);
dest.writeString(value);
dest.writeInt(selected ? 1 : 0);
}
public static final Parcelable.Creator<MultiChoiceItem> CREATOR = new Parcelable.Creator<MultiChoiceItem>() {
public MultiChoiceItem createFromParcel(Parcel in) {
return new MultiChoiceItem(in);
}
public MultiChoiceItem[] newArray(int size) {
return new MultiChoiceItem[size];
}
};
}
}
Run Code Online (Sandbox Code Playgroud)
还有一件活动就是onCreate()
...
mAdapter = new MultiListAdapter(this, R.id.head, mItems);
setListAdapter(mAdapter);
final ListView listView = getListView();
listView.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE);
listView.setItemsCanFocus(false);
...
Run Code Online (Sandbox Code Playgroud)
编辑:
在找到更好的解决方案之前,我在Activity中实现了检查:
...
int len = mListView.getCount();
for (int i = 0; i < len; i++) {
if (((MultiChoiceItem) mListView.getItemAtPosition(i)).selected) {
mListView.setItemChecked(i, true);
}
}
...
Run Code Online (Sandbox Code Playgroud)
我认为性能将是唯一的潜在问题,但我发现另一个 - 更严重.该列表启用了文本过滤器(mListView.setTextFilterEnabled(true)).这是失败的情况:
我假设setItemChecked()在选中的列表上标记了一个固定的位置,而我需要一些标记该位置的东西 - 即使列表上的位置发生变化也能保持状态.
虽然性能问题可能(在某些方面)被忽略 - 这个新问题实际上阻止了我,所以我真的很感激任何帮助.
Joh*_*ohn 29
如果您使用ListView.CHOICE_MODE_MULTIPLE或者CHOICE_MODE_SINGLE在getView调用后将由ListView覆盖项目的检查状态.您必须使用以下构造:
@Override
public View getView(int position, View convertView, ViewGroup parent) {
((ListView)parent).setItemChecked(position, true);
}
Run Code Online (Sandbox Code Playgroud)
另一种可能性是自己使用ListView.CHOICE_MODE_NONE和管理检查状态.
| 归档时间: |
|
| 查看次数: |
20805 次 |
| 最近记录: |