在listview android中滚动期间我的图像会发生变化

时间:2016-04-12 04:56:23

标签: android listview imageview

在上周,我只是试图解决这个问题。看到每个类似的问题,我不知道为什么,解决方案不适合我。 我有一个列表视图,每个项目都有一个图像视图。单击图像视图时,我想更改图像资源。好。全部完成。但滚动时,图像资源会发生变化。 我的完整代码是:

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;
}

}

我哪里有错误?

5 个答案:

答案 0 :(得分:6)

你必须在holder中使用一个布尔值来检查你的背景图像是否为特定行设置。

支架

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

设置图片

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);
}
希望这会有所帮助。

答案 1 :(得分:2)

这是因为当您滚动listview时,android系统始终会创建新行并销毁不可见的行。你需要修改getView(),如下所示,一切都会好的:

@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;
}

答案 2 :(得分:2)

试试这个,

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;
}
}

添加模型类:

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;
    }
}

答案 3 :(得分:1)

你应该在构造函数中定义layoutInflater,因为getView()调用每一行,所以如果你在getView()中定义layoutInflater,那么LayoutInflater会为每一行反复定义。

答案 4 :(得分:1)

是的,这个问题总是出现在ListView中,因为android总是在其中销毁并重新创建行。

您有两种选择:

首先,修改您的适配器以保存ListView中每一行的状态,并在显示该行之前检查此状态。

第二一,我推荐了这个并在我的代码中使用它,你可以使用RecyclerView,这个问题不会发生。