可扩展列表视图中的 Gridview 中的复选框在滚动时未被选中
Checkbox in Gridview in Expandable ListView getting unchecked on scroll
我有一个可展开的列表视图。在它的子项中是一个 gridview。在 gridview 里面有自定义复选框。
现在的问题是,当我勾选一个复选框并向下滚动,甚至关闭父视图时,勾选消失了。
像这样:
滚动前检查的屏幕:
滚动后检查的屏幕:
这是我的 ExpandableListView 适配器:
public class CreateProfileExpandableAdapter extends BaseExpandableListAdapter {
ArrayList<CreateProfileFecetsHeaderModel> al;
Activity activity;
public CreateProfileExpandableAdapter(Activity activity, ArrayList<CreateProfileFecetsHeaderModel> al) {
this.activity = activity;
this.al = al;
}
@Override
public Object getChild(int groupPosition, int childPosition) {
return al.get(groupPosition).getChildren();
}
@Override
public long getChildId(int groupPosition, int childPosition) {
return al.get(groupPosition).hashCode();
}
@Override
public View getChildView(int groupPosition, final int childPosition,
boolean isLastChild, View convertView, ViewGroup parent) {
View v = convertView;
if (v == null) {
LayoutInflater inflater = (LayoutInflater) activity.getSystemService
(Context.LAYOUT_INFLATER_SERVICE);
v = inflater.inflate(R.layout.create_profile_child, parent, false);
}
ExpandableHeightGridView gridViewChildren = (ExpandableHeightGridView) v.findViewById(R.id.gridViewChildren);
gridViewChildren.setExpanded(true);
CreateProfileChildAdapter createProfileChildAdapter = new CreateProfileChildAdapter(activity, al.get(groupPosition).getChildren());
gridViewChildren.setAdapter(createProfileChildAdapter);
return v;
}
@Override
public int getChildrenCount(int groupPosition) {
return 1;
}
@Override
public Object getGroup(int groupPosition) {
return al.get(groupPosition);
}
@Override
public int getGroupCount() {
return al.size();
}
@Override
public long getGroupId(int groupPosition) {
return al.get(groupPosition).hashCode();
}
@Override
public View getGroupView(int groupPosition, boolean isExpanded,
View convertView, ViewGroup parent) {
View v = convertView;
if (v == null) {
LayoutInflater inflater = (LayoutInflater) activity.getSystemService
(Context.LAYOUT_INFLATER_SERVICE);
v = inflater.inflate(R.layout.create_profile_group, parent, false);
}
TextView textViewGroup = (TextView) v.findViewById(R.id.textViewGroup);
textViewGroup.setText(al.get(groupPosition).getText());
return v;
}
@Override
public boolean hasStableIds() {
return false;
}
@Override
public boolean isChildSelectable(int groupPosition, int childPosition) {
return true;
}
}
网格视图适配器:
public class CreateProfileChildAdapter extends BaseAdapter {
Activity activity;
ArrayList<CreateProfileFecetsChildModel> al;
int index = -1;
public CreateProfileChildAdapter(Activity activity, ArrayList<CreateProfileFecetsChildModel> al) {
// TODO Auto-generated constructor stub
this.activity = activity;
this.al = al;
}
@Override
public int getCount() {
// TODO Auto-generated method stub
return al.size();
}
@Override
public Object getItem(int position) {
// TODO Auto-generated method stub
return al.get(position);
}
@Override
public long getItemId(int position) {
// TODO Auto-generated method stub
return position;
}
private static class ViewHolder {
CheckBox checkBoxChild;
}
@Override
public View getView(final int position, View convertView, ViewGroup parent) {
// TODO Auto-generated method stub
final ViewHolder viewHolder;
final int pos = position;
if (convertView == null) {
LayoutInflater inflater = LayoutInflater.from(activity);
convertView = inflater.inflate(R.layout.create_profile_grid_child, parent, false);
viewHolder = new ViewHolder();
viewHolder.checkBoxChild = (CheckBox) convertView.findViewById(R.id.checkBoxChild);
convertView.setTag(viewHolder);
} else {
viewHolder = (ViewHolder) convertView.getTag();
}
viewHolder.checkBoxChild.setText(al.get(position).getTitle());
viewHolder.checkBoxChild.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton compoundButton, boolean b) {
if (b) {
viewHolder.checkBoxChild.setTextColor(activity.getResources().getColor(R.color.white));
} else {
viewHolder.checkBoxChild.setTextColor(activity.getResources().getColor(R.color.black));
}
}
});
return convertView;
}
}
问题是视图在没有重置状态的情况下被回收。想象一下在一个屏幕上显示 20 个项目,但一次只显示四个项目,这意味着 GridViewAdapter 使用四个,也许五个视图。当滚动列表时,这些视图轮流显示您的项目:
解法:
- 您必须将有关视图状态的所有内容(在您的情况下:标记为选中的内容)存储在类型为
CreateProfileFecetsHeaderModel
. 的适配器子列表条目中
- 在您的 Adapter 的
getChildView()
中,使用 position
从您的 Adapter 的子项中获取选中状态,并相应地设置 holder 的 CheckBox。
由于它是可扩展适配器,您需要知道groupid、selectedchild、id。
尝试如下...
@Override
public View getChildView(int groupPosition, int childPosition,
boolean isLastChild, View convertView, ViewGroup parent) {
final Pair<Long, Long> tag = new Pair<Long, Long>(
getGroupId(groupPosition),
getChildId(groupPosition, childPosition));
ViewHolder viewHolder = null;
if (convertView == null) {
convertView = inflater.inflate(R.layout.item_countryoforigin, null);
viewHolder = new ViewHolder(convertView);
convertView.setTag(viewHolder);
} else {
viewHolder = (ViewHolder) convertView.getTag();
}
viewHolder.checkBox.setTag(tag);
viewHolder.checkBox.setChecked(mCheckedItems.contains(tag));
viewHolder.textview.setText((CharSequence) getText(groupPosition, childPosition));
viewHolder.checkBox.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
final CheckBox cb = (CheckBox) v;
final Pair<Long, Long> tag = (Pair<Long, Long>) v.getTag();
if (cb.isChecked()) {
mCheckedItems.add(tag);
} else {
mCheckedItems.remove(tag);
}
}
});
return convertView;
}
public Set<Pair<Long, Long>> getCheckedItems() {
return mCheckedItems;
}
你可以调用 getcheckitems .....
我有一个可展开的列表视图。在它的子项中是一个 gridview。在 gridview 里面有自定义复选框。
现在的问题是,当我勾选一个复选框并向下滚动,甚至关闭父视图时,勾选消失了。
像这样:
滚动前检查的屏幕:
滚动后检查的屏幕:
这是我的 ExpandableListView 适配器:
public class CreateProfileExpandableAdapter extends BaseExpandableListAdapter {
ArrayList<CreateProfileFecetsHeaderModel> al;
Activity activity;
public CreateProfileExpandableAdapter(Activity activity, ArrayList<CreateProfileFecetsHeaderModel> al) {
this.activity = activity;
this.al = al;
}
@Override
public Object getChild(int groupPosition, int childPosition) {
return al.get(groupPosition).getChildren();
}
@Override
public long getChildId(int groupPosition, int childPosition) {
return al.get(groupPosition).hashCode();
}
@Override
public View getChildView(int groupPosition, final int childPosition,
boolean isLastChild, View convertView, ViewGroup parent) {
View v = convertView;
if (v == null) {
LayoutInflater inflater = (LayoutInflater) activity.getSystemService
(Context.LAYOUT_INFLATER_SERVICE);
v = inflater.inflate(R.layout.create_profile_child, parent, false);
}
ExpandableHeightGridView gridViewChildren = (ExpandableHeightGridView) v.findViewById(R.id.gridViewChildren);
gridViewChildren.setExpanded(true);
CreateProfileChildAdapter createProfileChildAdapter = new CreateProfileChildAdapter(activity, al.get(groupPosition).getChildren());
gridViewChildren.setAdapter(createProfileChildAdapter);
return v;
}
@Override
public int getChildrenCount(int groupPosition) {
return 1;
}
@Override
public Object getGroup(int groupPosition) {
return al.get(groupPosition);
}
@Override
public int getGroupCount() {
return al.size();
}
@Override
public long getGroupId(int groupPosition) {
return al.get(groupPosition).hashCode();
}
@Override
public View getGroupView(int groupPosition, boolean isExpanded,
View convertView, ViewGroup parent) {
View v = convertView;
if (v == null) {
LayoutInflater inflater = (LayoutInflater) activity.getSystemService
(Context.LAYOUT_INFLATER_SERVICE);
v = inflater.inflate(R.layout.create_profile_group, parent, false);
}
TextView textViewGroup = (TextView) v.findViewById(R.id.textViewGroup);
textViewGroup.setText(al.get(groupPosition).getText());
return v;
}
@Override
public boolean hasStableIds() {
return false;
}
@Override
public boolean isChildSelectable(int groupPosition, int childPosition) {
return true;
}
}
网格视图适配器:
public class CreateProfileChildAdapter extends BaseAdapter {
Activity activity;
ArrayList<CreateProfileFecetsChildModel> al;
int index = -1;
public CreateProfileChildAdapter(Activity activity, ArrayList<CreateProfileFecetsChildModel> al) {
// TODO Auto-generated constructor stub
this.activity = activity;
this.al = al;
}
@Override
public int getCount() {
// TODO Auto-generated method stub
return al.size();
}
@Override
public Object getItem(int position) {
// TODO Auto-generated method stub
return al.get(position);
}
@Override
public long getItemId(int position) {
// TODO Auto-generated method stub
return position;
}
private static class ViewHolder {
CheckBox checkBoxChild;
}
@Override
public View getView(final int position, View convertView, ViewGroup parent) {
// TODO Auto-generated method stub
final ViewHolder viewHolder;
final int pos = position;
if (convertView == null) {
LayoutInflater inflater = LayoutInflater.from(activity);
convertView = inflater.inflate(R.layout.create_profile_grid_child, parent, false);
viewHolder = new ViewHolder();
viewHolder.checkBoxChild = (CheckBox) convertView.findViewById(R.id.checkBoxChild);
convertView.setTag(viewHolder);
} else {
viewHolder = (ViewHolder) convertView.getTag();
}
viewHolder.checkBoxChild.setText(al.get(position).getTitle());
viewHolder.checkBoxChild.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton compoundButton, boolean b) {
if (b) {
viewHolder.checkBoxChild.setTextColor(activity.getResources().getColor(R.color.white));
} else {
viewHolder.checkBoxChild.setTextColor(activity.getResources().getColor(R.color.black));
}
}
});
return convertView;
}
}
问题是视图在没有重置状态的情况下被回收。想象一下在一个屏幕上显示 20 个项目,但一次只显示四个项目,这意味着 GridViewAdapter 使用四个,也许五个视图。当滚动列表时,这些视图轮流显示您的项目:
解法:
- 您必须将有关视图状态的所有内容(在您的情况下:标记为选中的内容)存储在类型为
CreateProfileFecetsHeaderModel
. 的适配器子列表条目中
- 在您的 Adapter 的
getChildView()
中,使用position
从您的 Adapter 的子项中获取选中状态,并相应地设置 holder 的 CheckBox。
由于它是可扩展适配器,您需要知道groupid、selectedchild、id。 尝试如下...
@Override
public View getChildView(int groupPosition, int childPosition,
boolean isLastChild, View convertView, ViewGroup parent) {
final Pair<Long, Long> tag = new Pair<Long, Long>(
getGroupId(groupPosition),
getChildId(groupPosition, childPosition));
ViewHolder viewHolder = null;
if (convertView == null) {
convertView = inflater.inflate(R.layout.item_countryoforigin, null);
viewHolder = new ViewHolder(convertView);
convertView.setTag(viewHolder);
} else {
viewHolder = (ViewHolder) convertView.getTag();
}
viewHolder.checkBox.setTag(tag);
viewHolder.checkBox.setChecked(mCheckedItems.contains(tag));
viewHolder.textview.setText((CharSequence) getText(groupPosition, childPosition));
viewHolder.checkBox.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
final CheckBox cb = (CheckBox) v;
final Pair<Long, Long> tag = (Pair<Long, Long>) v.getTag();
if (cb.isChecked()) {
mCheckedItems.add(tag);
} else {
mCheckedItems.remove(tag);
}
}
});
return convertView;
}
public Set<Pair<Long, Long>> getCheckedItems() {
return mCheckedItems;
}
你可以调用 getcheckitems .....