用于列表项更新的 ListView 适配器 onClickListener
ListView adapter onClickListener for list item update
我知道这个问题已经被问过很多次了。但在尝试了很多解决方案后,我无法成功实现它。
我正在制作一个包含多个 View
的自定义布局列表。其中一个视图是 ImageView
,我希望它在用户单击它时更改其图标。
ListAdapter class我使用的是如下:
public class PetitionListAdapter extends BaseAdapter {
ViewHolder holder = null;
private LayoutInflater inflater;
private ArrayList<CustomObject> objects;
private class ViewHolder {
ImageView ivsign;
}
public PetitionListAdapter(Context context, ArrayList<CustomObject> objects) {
inflater = LayoutInflater.from(context);
this.objects = objects;
}
public int getCount() {
return objects.size();
}
public CustomObject getItem(int position) {
return objects.get(position);
}
public long getItemId(int position) {
return position;
}
public View getView(final int position, View convertView, ViewGroup parent) {
if (convertView == null) {
holder = new ViewHolder();
convertView = inflater.inflate(R.layout.petition_list_layout_beta, null);
holder.ivsign = convertView.findViewById(R.id.ivsign);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
holder.ivsign.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
ImageView img = v.findViewById(R.id.ivsign);
img.setImageResource(R.drawable.icon_after_click);
}
});
return convertView;
}
}
这样做,clickListener 起作用了,但它不是那个特定的 imageview,而是随机更改许多 imageview 的图标行。我知道它是因为 viewHolder。但是我怎样才能正确地做到这一点?
我也用过:-
imgViewArray[position] = holder.textView1;
里面 "onListItemClickListener"。这样做会根据需要更改该位置的图标,但在滚动并再次返回该行后,它再次更改为默认图标。我知道这是因为该行被回收了。
我认为你的问题出在你的 onClickListener
上。您在 ViewHolder
中为 ImageView
设置它,然后在 onClick
方法中设置 v.findViewById
。
你应该做的是
ImageView img = (ImageView) convertView.findViewById(R.id.ivsign);
然后
img.setOnClickListener(.......);
这对我有用,所以如果您在实施时遇到任何问题,请告诉我。
这不是好的做法。在 OnItemClick
中,您应该更改列表使用的对象列表,然后调用 notifyDataSetChanged()
。在 getView(...)
中,您应该简单地使 listView 反映列表中的值。
这样,当列表刷新时,视图的状态保持不变。
是的,您当然遇到了这个问题。为什么?因为当滚动列表视图时,您所有的 convert view
都被重复使用,每个 convertView
用于显示另一个 CustomObject
。这意味着如果您更改第一行图像,滚动后,重新使用 first-row convertView
的行将 image
显示为 clicked row
。那么,如何解决呢?您必须在 CustomObject
中保存项目的位置,例如:
public View getView(final int position, View convertView, ViewGroup parent) {
if (convertView == null) {
holder = new ViewHolder();
convertView = inflater.inflate(R.layout.petition_list_layout_beta, null);
holder.ivsign = convertView.findViewById(R.id.ivsign);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
final CustomObject object = listCustomObject.get(position);
holder.ivsign.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
((ImageView)v).setImageResource(R.drawable.icon_after_click);
object.saveResourceId(R.drawable.icon_after_click); // save your resource to use after scrolling.
}
});
// display resouce base on what's saved or display default image.
holder.ivSign.setImageResource(object.getSavedResourceId());
return convertView;
}
我知道这个问题已经被问过很多次了。但在尝试了很多解决方案后,我无法成功实现它。
我正在制作一个包含多个 View
的自定义布局列表。其中一个视图是 ImageView
,我希望它在用户单击它时更改其图标。
ListAdapter class我使用的是如下:
public class PetitionListAdapter extends BaseAdapter {
ViewHolder holder = null;
private LayoutInflater inflater;
private ArrayList<CustomObject> objects;
private class ViewHolder {
ImageView ivsign;
}
public PetitionListAdapter(Context context, ArrayList<CustomObject> objects) {
inflater = LayoutInflater.from(context);
this.objects = objects;
}
public int getCount() {
return objects.size();
}
public CustomObject getItem(int position) {
return objects.get(position);
}
public long getItemId(int position) {
return position;
}
public View getView(final int position, View convertView, ViewGroup parent) {
if (convertView == null) {
holder = new ViewHolder();
convertView = inflater.inflate(R.layout.petition_list_layout_beta, null);
holder.ivsign = convertView.findViewById(R.id.ivsign);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
holder.ivsign.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
ImageView img = v.findViewById(R.id.ivsign);
img.setImageResource(R.drawable.icon_after_click);
}
});
return convertView;
}
}
这样做,clickListener 起作用了,但它不是那个特定的 imageview,而是随机更改许多 imageview 的图标行。我知道它是因为 viewHolder。但是我怎样才能正确地做到这一点?
我也用过:-
imgViewArray[position] = holder.textView1;
里面 "onListItemClickListener"。这样做会根据需要更改该位置的图标,但在滚动并再次返回该行后,它再次更改为默认图标。我知道这是因为该行被回收了。
我认为你的问题出在你的 onClickListener
上。您在 ViewHolder
中为 ImageView
设置它,然后在 onClick
方法中设置 v.findViewById
。
你应该做的是
ImageView img = (ImageView) convertView.findViewById(R.id.ivsign);
然后
img.setOnClickListener(.......);
这对我有用,所以如果您在实施时遇到任何问题,请告诉我。
这不是好的做法。在 OnItemClick
中,您应该更改列表使用的对象列表,然后调用 notifyDataSetChanged()
。在 getView(...)
中,您应该简单地使 listView 反映列表中的值。
这样,当列表刷新时,视图的状态保持不变。
是的,您当然遇到了这个问题。为什么?因为当滚动列表视图时,您所有的 convert view
都被重复使用,每个 convertView
用于显示另一个 CustomObject
。这意味着如果您更改第一行图像,滚动后,重新使用 first-row convertView
的行将 image
显示为 clicked row
。那么,如何解决呢?您必须在 CustomObject
中保存项目的位置,例如:
public View getView(final int position, View convertView, ViewGroup parent) {
if (convertView == null) {
holder = new ViewHolder();
convertView = inflater.inflate(R.layout.petition_list_layout_beta, null);
holder.ivsign = convertView.findViewById(R.id.ivsign);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
final CustomObject object = listCustomObject.get(position);
holder.ivsign.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
((ImageView)v).setImageResource(R.drawable.icon_after_click);
object.saveResourceId(R.drawable.icon_after_click); // save your resource to use after scrolling.
}
});
// display resouce base on what's saved or display default image.
holder.ivSign.setImageResource(object.getSavedResourceId());
return convertView;
}