My images changing during scroll in listview android

吃可爱长大的小学妹 提交于 2019-12-08 16:00:34

问题


In last week, i just try to resolve this problem. see every similar questions and i don't know why, solutions don't work for me. I have a list view and each item has an image view. when clicked on image view , i want to change image resource. well. all done. but when scrolling, image resources change. my full code is:

public class CustomBaseAdapter extends BaseAdapter {

Context context;
ArrayList<String> items;

    public CustomBaseAdapter(Context context,ArrayList<String> items){
        this.context = context;
        this.items = items;
    }

private class ViewHolder{
    TextView titr;
    ImageView image;
}

@Override
public int getCount() {
    return items.size();
}

@Override
public Object getItem(int position) {
    return items.get(position);
}

@Override
public long getItemId(int position) {
    return items.hashCode();
}

@Override
public View getView(int position, View view, ViewGroup parent) {
    View vi = view;
    final ViewHolder holder ;
    LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    if(view==null){

        vi = inflater.inflate(R.layout.customlistitem,null);
        holder = new ViewHolder();
        holder.titr = (TextView) vi.findViewById(R.id.listtext);
        holder.image = (ImageView) vi.findViewById(R.id.listimg);
        holder.image.setTag(position);
        vi.setTag(holder);
    }
    else{
        holder = (ViewHolder) vi.getTag();
    }


    holder.titr.setText(items.get(position));

    holder.image.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
           v.setBackgroundResource(R.drawable.fav_ic);
        }
    });
    return vi;
}

}

where i have mistake?


回答1:


try this,

public class CustomBaseAdapter extends BaseAdapter {

Context context;
ArrayList<Items> items;

     public CustomBaseAdapter(Context context,ArrayList<Items> items){
        this.context = context;
        this.items = items;
    }

    private class ViewHolder{
    TextView titr;
    ImageView image;
    }

@Override
public int getCount() {
    return items.size();
}

@Override
public Items getItem(int position) {
    return items.get(position);
}

@Override
public long getItemId(int position) {
    return items.hashCode();
}

@Override
public View getView(int position, View view, ViewGroup parent) {
    View vi = view;
    final ViewHolder holder ;

    LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    if(view==null){

        vi = inflater.inflate(R.layout.customlistitem,null);
        holder = new ViewHolder();
        holder.titr = (TextView) vi.findViewById(R.id.listtext);
        holder.image = (ImageView) vi.findViewById(R.id.listimg);
        holder.image.setTag(position);
        vi.setTag(holder);
    }
    else{
        holder = (ViewHolder) vi.getTag();
    }


    holder.titr.setText(items.get(position).getStrTxt());
    holder.image.setImageResource(items.get(position).getDrawableImage());
    holder.image.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            items.set(position,new Items(R.drawable.fav_ic));
            notifyDataSetChanged();
        }
    });
    return vi;
}
}

Add Model Class :

public class Items {


    int drawableImage;
    String strTxt;


  public Items(int drawableImage) {
    this.drawableImage = drawableImage;
   }
    public int getDrawableImage() {
        return drawableImage;
    }

    public void setDrawableImage(int drawableImage) {
        this.drawableImage = drawableImage;
    }

    public String getStrTxt() {
        return strTxt;
    }

    public void setStrTxt(String strTxt) {
        this.strTxt = strTxt;
    }
}



回答2:


you have to use one boolean value in holder to check whether your background image is set or not for particular row.

holder

private class ViewHolder{
    TextView titr;
    ImageView image;
boolean isSet;
}

set image

holder.image.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
           v.setBackgroundResource(R.drawable.fav_ic);
holder.isSet = true
        }
    });

if(holder.isSet)
 {
holder.image.setBackgroundResource(R.drawable.fav_ic);
}
else{
holder.image.setBackgroundResource(no image or other image);
}

hope this will help.




回答3:


This is because when you scroll listview android system always create new row and destroy non-visible rows. You need to modify the getView() as below then everything will be fine :

@Override
public View getView(int position, View view, ViewGroup parent) {
    View vi = view;
    final ViewHolder holder ;
    LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);

SharedPreferences sp  = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());

    if(view==null){

        vi = inflater.inflate(R.layout.customlistitem,null);
        holder = new ViewHolder();
        holder.titr = (TextView) vi.findViewById(R.id.listtext);
        holder.image = (ImageView) vi.findViewById(R.id.listimg);
        holder.image.setTag(position);
        vi.setTag(holder);
    }
    else{
        holder = (ViewHolder) vi.getTag();
    }


    holder.titr.setText(items.get(position));
if(sp.getBoolean("position="+position, false)){
    v.setBackgroundResource(R.drawable.fav_ic);
}
    holder.image.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
           v.setBackgroundResource(R.drawable.fav_ic);

SharedPreferences.Editor edit = sp.edit();
edit.putBoolean("position="+position, true);
edit.commit();

        }
    });
    return vi;
}



回答4:


You should define layoutInflater in the constructor because getView() call for each row so if you define layoutInflater in getView() then LayoutInflater define again and again for each row.




回答5:


Yes, this problem appears always in ListView because android always destroy and recreate rows in it.

You have two choices:

First, Modify your Adapter to save status for each row in the ListView and check this status before displaying the row.

Second one, I recommended this one and use it in my code, you can use RecyclerView, this problem will not happen with it.



来源:https://stackoverflow.com/questions/36563923/my-images-changing-during-scroll-in-listview-android

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!