ListView 适配器行为异常
ListView adapter behaves strangely
ListView
适配器做了奇怪的事情。方法 getChecked()
(如下所示的适配器代码)没有 return 我期望的值。好像他迟到了一步。
为了便于理解,我将解释一下:我使用的是自定义 ListView
,每个项目包含一个 CheckBox
(和其他 Views
)。我想在按下按钮时显示选中元素的位置。这使得方法 getChecked()
。
但是会发生以下情况:我检查第二个和第四个列表项并单击按钮,结果 - [],然后我检查第 5 个项目,结果 - [2, 4],然后我清除所有 CheckBoxes
,结果 [2, 4, 5] 当我再次点击按钮时,我收到 - []。结果晚了一步
public class ContactAdapter extends BaseAdapter {
private LayoutInflater inflater;
private ArrayList<Contact> contacts;
private boolean isCheckBoxVisible;
private View view;
private int[] colors = {Color.BLACK, Color.BLUE, Color.RED, Color.GRAY, Color.GREEN};
private int currentMaleColor;
private int currentFemaleColor;
public ContactAdapter(Context context, ArrayList<Contact> contacts) {
this.contacts = contacts;
inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
isCheckBoxVisible = false;
setColors();
}
@Override
public int getCount() {
return contacts.size();
}
@Override
public Object getItem(int position) {
return contacts.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
private Contact getContact(int position) {
return (Contact) getItem(position);
}
public void setCheckBoxVisibility(boolean isVisible) {
isCheckBoxVisible = isVisible;
notifyDataSetChanged();
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
view = convertView;
if (view == null) {
view = inflater.inflate(R.layout.contact_item, parent, false);
}
CheckBox cb = (CheckBox) view.findViewById(R.id.lv_box);
if (isCheckBoxVisible) {
cb.setVisibility(View.VISIBLE);
} else {
cb.setVisibility(View.INVISIBLE);
}
Contact c = getContact(position);
((TextView) view.findViewById(R.id.lv_name)).setText(c.getName() + " " + c.getSurname());
((ImageView) view.findViewById(R.id.lv_img)).setImageBitmap(c.getPhoto());
if (c.getSex().equals("Man")) {
view.setBackgroundColor(currentMaleColor);
} else {
view.setBackgroundColor(currentFemaleColor);
}
boolean isCheck = ((CheckBox) view.findViewById(R.id.lv_box)).isChecked();
contacts.get(position).setChecked(isCheck);
return view;
}
public ArrayList<Integer> getChecked() {
notifyDataSetChanged();
ArrayList<Integer> IDs = new ArrayList<Integer>();
for (Contact c : contacts) {
if (c.isChecked()) IDs.add(c.getID());
}
return IDs;
}
private void setColors() {
int colorM = Integer.parseInt(MainActivity.sp.getString("lp_colorM", "0"));
int colorW = Integer.parseInt(MainActivity.sp.getString("lp_colorW", "0"));
currentMaleColor = colors[colorM];
currentFemaleColor = colors[colorW];
}
}
在我的 activity 中,我使用我的适配器,如下所示:
@Override
protected void onResume() {
super.onResume();
adapter = new ContactAdapter(getApplicationContext(), contacts);
list.setAdapter(adapter);
}
我的按钮代码:
ArrayList<Integer> al = adapter.getChecked();
Toast.makeText(this, al.toString(), Toast.LENGTH_LONG).show();
你怎么看这件事?我很乐意提供任何帮助。
如果 convertView == null,尝试获取视图状态
if (convertView == null) {
holder = new Holder();
convertView = mInflator.inflate(R.layout.row_viewproduct, null);
convertView.setTag(holder);
} else {
holder = (Holder) convertView.getTag();
}
// 设置从holder查看的数据
这不是答案,但想说你可以在下面使用
private void setColors() {
int colorM = Integer.parseInt(MainActivity.sp.getString("lp_colorM", "0"));
int colorW = Integer.parseInt(MainActivity.sp.getString("lp_colorW", "0"));
if(colorM < 5){
currentMaleColor = colors[colorM];
}
if(colorW < 5){
currentFemaleColor = colors[colorM];
}
}
要回答您的问题,请查看视图持有者模式
http://ricston.com/blog/optimising-listview-viewholder-pattern/
在njzk2的建议下,我改成了:
boolean isCheck = ((CheckBox) view.findViewById(R.id.lv_box)).isChecked();
contacts.get(position).setChecked(isCheck);
此时:
CheckBox checkBox = (CheckBox) view.findViewById(R.id.lv_box);
checkBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
contacts.get(position).setChecked(isChecked);
}
});
现在可以了:)
ListView
适配器做了奇怪的事情。方法 getChecked()
(如下所示的适配器代码)没有 return 我期望的值。好像他迟到了一步。
为了便于理解,我将解释一下:我使用的是自定义 ListView
,每个项目包含一个 CheckBox
(和其他 Views
)。我想在按下按钮时显示选中元素的位置。这使得方法 getChecked()
。
但是会发生以下情况:我检查第二个和第四个列表项并单击按钮,结果 - [],然后我检查第 5 个项目,结果 - [2, 4],然后我清除所有 CheckBoxes
,结果 [2, 4, 5] 当我再次点击按钮时,我收到 - []。结果晚了一步
public class ContactAdapter extends BaseAdapter {
private LayoutInflater inflater;
private ArrayList<Contact> contacts;
private boolean isCheckBoxVisible;
private View view;
private int[] colors = {Color.BLACK, Color.BLUE, Color.RED, Color.GRAY, Color.GREEN};
private int currentMaleColor;
private int currentFemaleColor;
public ContactAdapter(Context context, ArrayList<Contact> contacts) {
this.contacts = contacts;
inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
isCheckBoxVisible = false;
setColors();
}
@Override
public int getCount() {
return contacts.size();
}
@Override
public Object getItem(int position) {
return contacts.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
private Contact getContact(int position) {
return (Contact) getItem(position);
}
public void setCheckBoxVisibility(boolean isVisible) {
isCheckBoxVisible = isVisible;
notifyDataSetChanged();
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
view = convertView;
if (view == null) {
view = inflater.inflate(R.layout.contact_item, parent, false);
}
CheckBox cb = (CheckBox) view.findViewById(R.id.lv_box);
if (isCheckBoxVisible) {
cb.setVisibility(View.VISIBLE);
} else {
cb.setVisibility(View.INVISIBLE);
}
Contact c = getContact(position);
((TextView) view.findViewById(R.id.lv_name)).setText(c.getName() + " " + c.getSurname());
((ImageView) view.findViewById(R.id.lv_img)).setImageBitmap(c.getPhoto());
if (c.getSex().equals("Man")) {
view.setBackgroundColor(currentMaleColor);
} else {
view.setBackgroundColor(currentFemaleColor);
}
boolean isCheck = ((CheckBox) view.findViewById(R.id.lv_box)).isChecked();
contacts.get(position).setChecked(isCheck);
return view;
}
public ArrayList<Integer> getChecked() {
notifyDataSetChanged();
ArrayList<Integer> IDs = new ArrayList<Integer>();
for (Contact c : contacts) {
if (c.isChecked()) IDs.add(c.getID());
}
return IDs;
}
private void setColors() {
int colorM = Integer.parseInt(MainActivity.sp.getString("lp_colorM", "0"));
int colorW = Integer.parseInt(MainActivity.sp.getString("lp_colorW", "0"));
currentMaleColor = colors[colorM];
currentFemaleColor = colors[colorW];
}
}
在我的 activity 中,我使用我的适配器,如下所示:
@Override
protected void onResume() {
super.onResume();
adapter = new ContactAdapter(getApplicationContext(), contacts);
list.setAdapter(adapter);
}
我的按钮代码:
ArrayList<Integer> al = adapter.getChecked();
Toast.makeText(this, al.toString(), Toast.LENGTH_LONG).show();
你怎么看这件事?我很乐意提供任何帮助。
如果 convertView == null,尝试获取视图状态
if (convertView == null) {
holder = new Holder();
convertView = mInflator.inflate(R.layout.row_viewproduct, null);
convertView.setTag(holder);
} else {
holder = (Holder) convertView.getTag();
}
// 设置从holder查看的数据
这不是答案,但想说你可以在下面使用
private void setColors() {
int colorM = Integer.parseInt(MainActivity.sp.getString("lp_colorM", "0"));
int colorW = Integer.parseInt(MainActivity.sp.getString("lp_colorW", "0"));
if(colorM < 5){
currentMaleColor = colors[colorM];
}
if(colorW < 5){
currentFemaleColor = colors[colorM];
}
}
要回答您的问题,请查看视图持有者模式 http://ricston.com/blog/optimising-listview-viewholder-pattern/
在njzk2的建议下,我改成了:
boolean isCheck = ((CheckBox) view.findViewById(R.id.lv_box)).isChecked();
contacts.get(position).setChecked(isCheck);
此时:
CheckBox checkBox = (CheckBox) view.findViewById(R.id.lv_box);
checkBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
contacts.get(position).setChecked(isChecked);
}
});
现在可以了:)