BaseAdapter выбор элемента и проблема обработки
У меня есть ListView
, который расширяет BaseAdapter
. У меня есть массив данных []. ListView
раздувается и заселяется правильно. То, что я пытаюсь сделать, - это сделать ImageView
видимым на элементе списка (в основном изображение проверки в правой части раздутого представления), когда пользователь выбирает элемент, и если был выбран предыдущий элемент, я просто скрываю этот ImageView
. Это тоже прекрасно работает.
Но после того, как я выбираю новый элемент и прокручиваю назад и вперед, я вижу странное поведение, изображение проверки иногда видно в нескольких элементы списка или скрыт в фактическом элементе, который в данный момент выбран. Не мог бы кто-нибудь помочь и объяснить, что я делаю не так?
У меня есть эти две строки в методе onCreate
:
adap = new EfficientAdapter(this);
lstview.setAdapter(adap);
И код адаптера:
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];
}
}
1 ответ:
Но после того, как я выбираю новый элемент и прокручиваю его вперед и назад, я вижу wierd поведение, изображение проверки иногда видно в нескольких элементах списка или скрыт в фактическом элементе, который в данный момент выбран.
Это, скорее всего, происходит из-за того, как вы устанавливаете прослушиватель кликов для
В любом случае, если вы просто хотите иметь только одну строку с видимым изображением, есть гораздо более простой способ сделать это. Прежде всего, вы должны отброситьconvertView
. Вы устанавливаетеOnCLickListener
только для случая, когдаconvertView
являетсяnull
, но при прокруткеListView
вверх и вниз, строки будут переработаны, и вы получите тот же слушатель, что и другие строки.OnCLickListener
наconvertView
и использоватьOnItemClickListener
на вашем элементеListView
. Из этого обратного вызова слушателя вы измените строки: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); } });
Затем измените адаптер следующим образом:
// 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; }