我的图像在listview android中滚动时发生更改

我的图像在listview android中滚动时发生更改,android,listview,imageview,Android,Listview,Imageview,在上周,我只是试图解决这个问题。看到每一个类似的问题,我不知道为什么,解决方案不适合我。 我有一个列表视图,每个项目都有一个图像视图。单击图像视图时,我想更改图像资源。好。都做完了。但当滚动时,图像资源会发生变化。 我的全部代码是: public class CustomBaseAdapter extends BaseAdapter { Context context; ArrayList<String> items; public CustomBaseAdapter(C

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

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;
}
公共类CustomBaseAdapter扩展BaseAdapter{
语境;
数组列表项;
公共CustomBaseAdapter(上下文、ArrayList项){
this.context=上下文;
这个项目=项目;
}
私有类视窗持有者{
文本视图标题;
图像视图图像;
}
@凌驾
public int getCount(){
返回items.size();
}
@凌驾
公共对象getItem(int位置){
返回项目。获取(位置);
}
@凌驾
公共长getItemId(int位置){
返回items.hashCode();
}
@凌驾
公共视图getView(内部位置、视图视图、视图组父视图){
视图vi=视图;
最终持票人;
LayoutFlater充气器=(LayoutFlater)context.getSystemService(context.LAYOUT\u充气器\u服务);
如果(视图==null){
vi=充气机充气(R.layout.customlistitem,空);
holder=新的ViewHolder();
holder.titr=(TextView)vi.findViewById(R.id.listtext);
holder.image=(ImageView)vi.findViewById(R.id.listimg);
支架.图像.设置标签(位置);
vi.setTag(支架);
}
否则{
holder=(ViewHolder)vi.getTag();
}
holder.titr.setText(items.get(position));
holder.image.setOnClickListener(新视图.OnClickListener(){
@凌驾
公共void onClick(视图v){
v、 挫折资源(R.drawable.fav_ic);
}
});
返回vi;
}
}


我哪里出错了?

这是因为当您滚动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;
}

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

持有者

设置图像


希望这会有所帮助。

您应该在构造函数中定义layoutInflater,因为getView()会调用每一行,所以如果您在getView()中定义layoutInflater,那么layoutInflater会为每一行定义一次又一次

试试这个

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

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

你有两个选择:

首先,修改适配器以保存
列表视图中每一行的状态
,并在显示该行之前检查该状态


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

这段代码看起来很棒。但在第行:“items.set(position).setDrawableImage(R.drawable.fav_ic);”应该改为items.get()谢谢。你的代码是正确的。我的问题解决了。
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);
}
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;
    }
}