如何在自定义ListView中更新ImageView的图像



我正在尝试单击自定义列表视图的imageview,并希望在onClick事件中更改它们的图像。我可以点击它成功做我的其他操作,但图像没有反映在图像视图中。

这是供参考的代码。

public class ReminderAdapter extends BaseAdapter {
private Activity activity;   
private static LayoutInflater inflater=null;
ImageView firstStar,secondStar,thirdStar,fourthStar,fifthStar;   
public ReminderAdapter(Activity a, ArrayList<HashMap<String, String>> d) {
    activity = a;
    data=d;
    inflater = (LayoutInflater)activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    faceBold = Typeface.createFromAsset(activity.getAssets(),
            "fonts/eau_sans_bold.otf");
    faceNormal = Typeface.createFromAsset(activity.getAssets(),
            "fonts/eau_sans_book.otf");         
}
public int getCount() {
    return data.size();
}
public Object getItem(int position) {
    return position;
}
public long getItemId(int position) {
    return position;
}    
public View getView(int position, View convertView, ViewGroup parent) {
    View vi=convertView;        

   if(activity instanceof SearchDishoom)
   {
       if(convertView==null)
           vi = inflater.inflate(R.layout.remind_dish_list_row, null);        
       firstStar = (ImageView)vi.findViewById(R.id.hotelListFirstStar);
       secondStar = (ImageView)vi.findViewById(R.id.hotelListSecondStar);
       thirdStar = (ImageView)vi.findViewById(R.id.hotelListThirdStar);
       fourthStar = (ImageView)vi.findViewById(R.id.hotelListFourthStar);
       fifthStar = (ImageView)vi.findViewById(R.id.hotelListFifthStar);
       firstStar.setFocusable(false);
       secondStar.setFocusable(false);
       thirdStar.setFocusable(false);
       fourthStar.setFocusable(false);
       fifthStar.setFocusable(false);           
       firstStar.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View arg0) {
            setStar(1);
        }
    });
       secondStar.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View arg0) {
            //ReminderList.clear();
            setStar(2);                 
        }
    });
       thirdStar.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View arg0) {
            setStar(3);                 
        }
    });
       fourthStar.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View arg0) {
            setStar(4);                 
        }
    });
       fifthStar.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View arg0) {                
            setStar(5);                 
        }
    });           
   }       
    return vi;
}

  public void setStar(int btnNumber) {
    if (btnNumber == 1) {       
        firstStar.setImageResource(R.drawable.rated);
        secondStar.setImageResource(R.drawable.unrated);
        thirdStar.setImageResource(R.drawable.unrated);
        fourthStar.setImageResource(R.drawable.unrated);
        fifthStar.setImageResource(R.drawable.unrated);
        //postRating(1);
    }
    if (btnNumber == 2) {           
        firstStar.setImageResource(R.drawable.rated);
        secondStar.setImageResource(R.drawable.rated);
        thirdStar.setImageResource(R.drawable.unrated);
        fourthStar.setImageResource(R.drawable.unrated);
        fifthStar.setImageResource(R.drawable.unrated);
        //postRating(2);
    }
    if (btnNumber == 3) {           
        firstStar.setImageResource(R.drawable.rated);
        secondStar.setImageResource(R.drawable.rated);
        thirdStar.setImageResource(R.drawable.rated);
        fourthStar.setImageResource(R.drawable.unrated);
        fifthStar.setImageResource(R.drawable.unrated);
        //postRating(3);
    }
    if (btnNumber == 4) {
        firstStar.setImageResource(R.drawable.rated);
        secondStar.setImageResource(R.drawable.rated);
        thirdStar.setImageResource(R.drawable.rated);
        fourthStar.setImageResource(R.drawable.rated);
        fifthStar.setImageResource(R.drawable.unrated);
        //postRating(4);
    }
    if (btnNumber == 5) {
        firstStar.setImageResource(R.drawable.rated);
        secondStar.setImageResource(R.drawable.rated);
        thirdStar.setImageResource(R.drawable.rated);
        fourthStar.setImageResource(R.drawable.rated);
        fifthStar.setImageResource(R.drawable.rated);
        //postRating(5);
    }
}   

我不明白发生了什么。请给我任何参考或提示
提前谢谢。

试试这个

 firstStar.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View arg0) {
            setStar(1);
            listAdapter.notifyDataSetChanged();
        }
    });

您的代码看起来有点bug。

默认情况下,适配器重用其子视图,所以处理适配器的一个重要点是更新正确目标的值。

在您的代码中,当用户单击firstStart时,将调用setStar方法。

firstStar.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View arg0) {
        setStar(1);
    }
}

setStar中,您引用了fireStart实例,但不能保证fireStar实例连接到期望的实例。例如,如果ListView中有多个项,那么每当调用getView方法时,就会覆盖fireStart实例。

public void setStar(int btnNumber) {
    if (btnNumber == 1) {
        firstStar.setImageResource(R.drawable.rated);
        ...
        //postRating(1);
    }
    ...
}

所以,您需要的是维护对正确目标的引用。一个简单的归档方法是在适配器中使用ViewHolder模式。像这样的。。。

class ViewHolder {
    View firstStar;
    View secondStar;
    ...
}
ViewHolder holder = new ViewHolder();
holder.firstStar = firstStar;
holder.secondStar = secondStar;
fireStar.setTag(holder);
firstStar.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View arg0) {
        ViewHolder holder = arg0.getTag();
        //update images inside holder,
        //instead of refer 'adapter instance scope field members'.
        holder.firstStar.setImageResource(R.drawable.rated);
    }
}

有一篇关于android中ViewHolder模式的好文章,Check-http://developer.android.com/training/improving-layouts/smooth-scrolling.html#ViewHolder

notifyDataSetChanged()----通知附加的观察者基础数据已更改,任何反映数据集的视图都应自行刷新。

这意味着,任何显示/基于/使用该数据的视图都应该无效(重新测量、重新绘制),以便向用户显示新的数据集。

NotifyDataSetChanged

firstStar.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View arg0) {
            setStar(1);
            your_adapter.notifyDataSetChanged();
        }