我有一个带有复选框的列表视图。我点击特定项目,相应的复选框被选中,但它也会在列表视图中的每8-10行后重复选中复选框。我明白这是因为在android中,只存储可见屏幕的视图被存储用于内存优化。但我无法克服这种情况。请建议。
public class FBFriendsListAdaptor extends ArrayAdapter<FBFriendItem>{
private final Context context;
private static List<FBFriendItem> items;
private SparseArray<FBFriendItem> checkedItems = new SparseArray<FBFriendItem>();
ViewHolder holder;
public FBFriendsListAdaptor(Context context, List<FBFriendItem> items) {
super(context, R.layout.fb_friend_list, items);
this.items = items;
this.context = context;
}
@Override
public FBFriendItem getItem(int position) {
// TODO Auto-generated method stub
return items.get(position);
}
public View getView(final int position, View convertView, ViewGroup parent) {
View v = convertView;
if (v == null) {
LayoutInflater vi = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
v = vi.inflate(R.layout.fb_friend_list, parent, false);
}
holder = new ViewHolder();
holder.selectFriendCB = (CheckBox)v.findViewById(R.id.selectFriendCB);
v.setTag(holder);
v.setOnClickListener(new View.OnClickListener(){
public void onClick(View v) {
if (checkedItems.get(position) != null){
checkedItems.remove(position);
holder.selectFriendCB.setChecked(false);
}
else {
checkedItems.put(position, items.get(position));
holder.selectFriendCB.setChecked(true);
}
}
});
FBFriendItem item = items.get(position);
TextView firstNameTV = (TextView) v.findViewById(R.id.firstNameTV);
TextView lastNameTV = (TextView) v.findViewById(R.id.lastNameTV);
ImageView picIV = (ImageView) v.findViewById(R.id.picIV);
if (!item.getFbId().isEmpty()) {
firstNameTV.setText(" " + item.getFirstName());
lastNameTV.setText(" " + item.getLastName());
Bitmap image = item.getImage();
if(image != null) {
picIV.setImageBitmap(image);
}
}
return v;
}
public SparseArray<FBFriendItem> getCheckedItems(){
return checkedItems;
}
static class ViewHolder {
CheckBox selectFriendCB;
}
}
答案 0 :(得分:1)
我注意到的第一件事是
if (!item.getFbId().isEmpty()) {
firstNameTV.setText(" " + item.getFirstName());
lastNameTV.setText(" " + item.getLastName());
Bitmap image = item.getImage();
if(image != null) {
picIV.setImageBitmap(image);
}
}
仅在某些情况下设置这些值是一个很大的禁忌。请记住,您的视图正在被重用,因此如果您设置了这些属性中的任何一个,则不能指望它们具有默认值。它们可能仍然是从最后一项设置的。尝试看起来更像这样的逻辑:
if (!item.getFbId().isEmpty()) {
firstNameTV.setText(" " + item.getFirstName());
lastNameTV.setText(" " + item.getLastName());
Bitmap image = item.getImage();
if(image == null) {
// reset the default because this view might have last displayed an
// item with a non-default value
picIV.setImageBitmap(myDefaultImage);
} else {
picIV.setImageBitmap(image);
}
} else {
// reset the defaults because this view might have last displayed an
// item with a non-default value
firstNameTV.setText(null);
lastNameTV.setText(null);
picIV.setImageBitmap(myDefaultImage);
}
接下来我注意到,对托运物品的管理是完全错误的。是否检查项目的状态应由ListView
管理,而不是您的适配器。我不知道你想要实现什么样的外观,所以我不打算详细说明如何布置你的项目,但你想要开始删除CheckBox
元素并查看{{ 1}}。 http://developer.android.com/reference/android/widget/AbsListView.html#setChoiceMode%28int%29
答案 1 :(得分:0)
这就是它的工作原理。我在FBFriendItem类中添加了一个“boolean selected = false”。 下面是数组适配器中的getView()代码:
public View getView(final int position, View convertView, ViewGroup parent) {
ViewHolder holder = null;
View v = convertView;
if (v == null) {
LayoutInflater vi = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
v = vi.inflate(R.layout.fb_friend_list, null);
holder = new ViewHolder();
holder.picIV = (ImageView)v.findViewById(R.id.picIV);
holder.firstNameTV = (TextView)v.findViewById(R.id.firstNameTV);
holder.lastNameTV = (TextView)v.findViewById(R.id.lastNameTV);
holder.selectFriendCB = (CheckBox)v.findViewById(R.id.selectFriendCB);
v.setTag(holder);
holder.selectFriendCB.setOnClickListener(new View.OnClickListener(){
public void onClick(View v) {
CheckBox cb = (CheckBox)v;
FBFriendItem item = (FBFriendItem)cb.getTag();
item.setSelected(cb.isChecked());
}
});
}
else {
holder = (ViewHolder)v.getTag();
}
FBFriendItem item = items.get(position);
holder.picIV.setImageBitmap(item.getImageBitmap());
holder.firstNameTV.setText(item.getFirstName());
holder.lastNameTV.setText(item.getLastName());
holder.selectFriendCB.setChecked(item.isSelected());
holder.selectFriendCB.setTag(item);
return v;
}
private class ViewHolder {
ImageView picIV;
TextView firstNameTV;
TextView lastNameTV;
CheckBox selectFriendCB;
}