[英]BaseAdapter selecting item and processing issue
I have a ListView
which extends BaseAdapter
. 我有一个扩展
BaseAdapter
的ListView
。 I have a data[] array. 我有一个data []数组。 The
ListView
inflates and populates correctly. ListView
正确地膨胀和填充。 What I am trying to do is make a ImageView
visible on the list item (basically a check image on the right side of the inflated view) when the user selects the item and if there was a previous item selected, I just hide that ImageView
. 我想要做的是当用户选择项目时,在列表项目上显示一个
ImageView
(基本上是膨胀视图右侧的检查图像),如果选择了上一个项目,我只是隐藏了ImageView
。 This works fine too. 这也很好。
But after I select a new item and scroll back and forth I see weird behavior, the check image is sometimes visible in multiple list items or is hidden in the actual item that is currently selected. 但是在我选择一个新项目并来回滚动后,我看到了奇怪的行为,检查图像有时在多个列表项中可见,或隐藏在当前选中的实际项目中。 Could someone please help and explain what I am doing wrong?
有人可以帮忙解释我做错了什么吗?
I have these two lines in the onCreate
method: 我在
onCreate
方法中有这两行:
adap = new EfficientAdapter(this);
lstview.setAdapter(adap);
and the adapter code: 和适配器代码:
public static class EfficientAdapter extends BaseAdapter implements Filterable {
private LayoutInflater mInflater;
private Context context;
private ImageView CurrentSelectedImageView;
private Integer CurrentPosition = 14;
public EfficientAdapter(Context context) {
mInflater = LayoutInflater.from(context);
this.context = context;
}
public View getView(final int position, View convertView, ViewGroup parent) {
ViewHolder holder;
//Log.e("TAG",String.valueOf(position));
if (convertView == null) {
convertView = mInflater.inflate(R.layout.adaptor_content, null);
holder = new ViewHolder();
holder.textLine = (TextView) convertView.findViewById(R.id.txtCategoryCaption);
holder.iconLine = (ImageView) convertView.findViewById(R.id.iconLine);
holder.imgCheckbox = (ImageView) convertView.findViewById(R.id.imgCheck);
//If the CurrentPosition == position then make the checkbox visible else dont.
if (CurrentPosition == position){
holder.imgCheckbox.setVisibility(View.VISIBLE);
}else{
holder.imgCheckbox.setVisibility(View.INVISIBLE);
}
final ImageView Checkbox = holder.imgCheckbox;
//Now if the list item is clicked then set the position as the current item and make the checkbox visible.
convertView.setOnClickListener(new OnClickListener() {
private int pos = position;
@Override
public void onClick(View v) {
if (CurrentSelectedImageView!=null){
CurrentSelectedImageView.setVisibility(View.INVISIBLE);
}
Checkbox.setVisibility(View.VISIBLE);
CurrentSelectedImageView = Checkbox;
CurrentPosition = pos;
}
});
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
int id = context.getResources().getIdentifier("nodeinsert", "drawable", context.getString(R.string.package_str));
if (id != 0x0) {
mIcon1 = BitmapFactory.decodeResource(context.getResources(), id);
}
holder.iconLine.setImageBitmap(mIcon1);
holder.textLine.setText(String.valueOf(data[position]));
if (CurrentPosition == position){
Log.e("TAG",CurrentPosition + "---" + String.valueOf(position));
holder.imgCheckbox.setVisibility(View.VISIBLE);
}else{
holder.imgCheckbox.setVisibility(View.INVISIBLE);
}
return convertView;
}
static class ViewHolder {
TextView textLine;
ImageView iconLine;
ImageView imgCheckbox;
}
@Override
public Filter getFilter() {
// TODO Auto-generated method stub
return null;
}
@Override
public long getItemId(int position) {
// TODO Auto-generated method stub
return 0;
}
@Override
public int getCount() {
// TODO Auto-generated method stub
return data.length;
}
@Override
public Object getItem(int position) {
// TODO Auto-generated method stub
return data[position];
}
}
But after I select a new item and scroll back and forth I see wierd behavior, the check image is sometimes visible in multiple list items or is hidden in the actual item that is currently selected.
但是在我选择一个新项目并来回滚动后,我看到了奇怪的行为,检查图像有时在多个列表项中可见,或者隐藏在当前选中的实际项目中。
That's most likely happening because of the way you set the click listener for convertView
. 由于您为
convertView
设置单击侦听器的方式,这很可能发生。 You set the OnCLickListener
only for the case when convertView
is null
but as you scroll the ListView
up and down, rows will get recycled and you would end up with the same listener as other rows. 您只为
convertView
为null
时的情况设置OnCLickListener
,但是当您向上和向下滚动ListView
时,行将被回收,您最终将获得与其他行相同的侦听器。
Anyway if you just want to have only one row with the image visible there is a much simpler way to do it. 无论如何,如果你只想让一行显示图像,那么有一种更简单的方法。 First of all you should drop the
OnCLickListener
on the convertView
and use the OnItemClickListener
on your ListView
element. 首先,您应该在
convertView
上删除OnCLickListener
,并在ListView
元素上使用OnItemClickListener
。 From this listener callback you'll modify the rows: 从这个监听器回调你将修改行:
lstview.setOnItemClickListener(new OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> l, View v, int position,
long id) {
View oldView = l.getChildAt(adap.getSelectedPosition());
ImageView img;
if (oldView != null && adap.getSelectedPosition() != -1) {
img = (ImageView) oldView.findViewById(R.id.imageView1);
img.setVisibility(View.INVISIBLE);
}
img = (ImageView) v.findViewById(R.id.imageView1);
img.setVisibility(View.VISIBLE);
adap.setSelectedPosition(position);
}
});
Then modify the adapter like this: 然后像这样修改适配器:
// a field in the adapter
private int mSelectedPosition = -1;
// getter and setter methods for the field above
public void setSelectedPosition(int selectedPosition) {
mSelectedPosition = selectedPosition;
notifyDataSetChanged();
}
public int getSelectedPosition() {
return mSelectedPosition;
}
// and finally your getView() method
public View getView(final int position, View convertView, ViewGroup parent) {
ViewHolder holder;
if (convertView == null) {
convertView = mInflater.inflate(R.layout.adaptor_content, parent, false);
holder = new ViewHolder();
holder.textLine = (TextView) convertView.findViewById(R.id.txtCategoryCaption);
holder.iconLine = (ImageView) convertView.findViewById(R.id.iconLine);
holder.imgCheckbox = (ImageView) convertView.findViewById(R.id.imgCheck);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
if (mSelectedPosition == position) {
holder.imgCheckbox.setVisibility(View.VISIBLE);
} else {
holder.imgCheckbox.setVisibility(View.INVISIBLE);
}
// what is the point of this call?!
// you should move this to another place(like the adapter's constructor), the getIdentifier()
// method is a bit slow and you call it each time the adapter calls getView()
// you should never use it in the getView() method(), especially as all you do is get the id of the same drawable again and again
int id = context.getResources().getIdentifier("nodeinsert", "drawable", context.getString(R.string.package_str));
// ?!?
if (id != 0x0) {
mIcon1 = BitmapFactory.decodeResource(context.getResources(), id);
}
holder.iconLine.setImageBitmap(mIcon1);
holder.textLine.setText(String.valueOf(data[position]));
return convertView;
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.