Android listview using ViewHolder

Mark picture Mark · Jul 21, 2014 · Viewed 35.2k times · Source

I have a problem. I'm attempting to change an icon in my listview after it has been clicked. It works correctly although are not modified only the clicked icons but also those who are not displayed. For example if I click the icon in the first item of the listview, also the fifth icon changes. This behaviour is repeated for all the following items (every five items of the listview). This is my getView method:

   public class AlphabeticalAdapter extends ArrayAdapter<String>
   {
       int layoutResourceId; 
       private final Context context;
       private List<String> data;
       private ProgressDialog mProgressDialog;
       private ImageView downloadImageButton;


       public AlphabeticalAdapter(Context context, int resource, List<String> data){
           super(context, resource, data);
           this.layoutResourceId = resource;
           this.context = context;
           this.data = data;    
       }

       public View getView(int position, View convertView, ViewGroup parent) {

          // View rowView = convertView;
           final ViewHolder viewHolder;

           if (convertView == null) {

               LayoutInflater inflater = (LayoutInflater) context
                        .getSystemService(Context.LAYOUT_INFLATER_SERVICE);


               convertView  = inflater.inflate(R.layout.catalogslist_single_row, parent, false);

           viewHolder = new ViewHolder();

           viewHolder.catlogTitle=(TextView)convertView.findViewById(R.id.txtTitle);
           viewHolder.icon=(ImageView)convertView.findViewById(R.id.imageView2); 
           viewHolder.downloadImageButton=(ImageView)convertView.findViewById(R.id.downloadImageButton);

           //downloadImageButton = (ImageView)rowView.findViewById(R.id.downloadImageButton);

           viewHolder.position = position;


           viewHolder.downloadImageButton.setOnClickListener(new OnClickListener() {
               @Override  
               public void onClick(View v) {
                     System.out.println("DOWNLOAD PRESSED");

                     viewHolder.downloadImageButton = (ImageView)v.findViewById(R.id.downloadImageButton);
                     viewHolder.downloadImageButton.setImageResource(R.drawable.icon_ok);
                     viewHolder.downloadImageButton.setTag("downloaded");
                     //rowView.setTag("downloaded");


                 }
             });



           convertView.setTag(viewHolder);

           }

           else{
               viewHolder= (ViewHolder)convertView.getTag(); 
           }

           viewHolder.catlogTitle.setText(data.get(position));
           viewHolder.catlogTitle.setTypeface(regularDin);
           viewHolder.icon.setImageResource(R.drawable.cata);


           if(viewHolder.downloadImageButton.getTag() == "downloaded"){
             downloadImageButton = (ImageView)convertView.findViewById(R.id.downloadImageButton);
             downloadImageButton.setImageResource(R.drawable.icon_ok);
           }
           else{
               downloadImageButton = (ImageView)convertView.findViewById(R.id.downloadImageButton);
                 downloadImageButton.setImageResource(R.drawable.icon_download);
           }


           viewHolder.position = position;

        return convertView;

       } //close getView 

...

And this is my ViewHolder class:

      static class ViewHolder{
       ImageView downloadImageButton;
       TextView catlogTitle;
       ImageView icon;
       int position;
   }

Answer

Divyang Metaliya picture Divyang Metaliya · Jul 21, 2014

Change your code at below. I think you're missing that.

public class AlphabeticalAdapter extends ArrayAdapter<String> {
    int layoutResourceId;
    private final Context context;
    private List<String> data;
    private List<String> tags;
    private ProgressDialog mProgressDialog;
    private ImageView downloadImageButton;

    public AlphabeticalAdapter(Context context, int resource, List<String> data) {
        super(context, resource, data);
        this.layoutResourceId = resource;
        this.context = context;
        this.data = data;
        tags = new ArrayList<String>();
        int size = data.size();
        for (int i = 0; i < size; i++) {
            tags.add("tag");
        }
    }

    static class ViewHolder {
        ImageView downloadImageButton;
        TextView catlogTitle;
        ImageView icon;
        int position;
    }

    public View getView(final int position, View convertView, ViewGroup parent) {

        // View rowView = convertView;
        final ViewHolder viewHolder;

        if (convertView == null) {
            LayoutInflater inflater = (LayoutInflater) context
                    .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            // convertView = inflater.inflate(R.layout.catalogslist_single_row,
            // parent, false);
            viewHolder = new ViewHolder();
            viewHolder.position = position;
            viewHolder.downloadImageButton
                    .setOnClickListener(new OnClickListener() {
                        @Override
                        public void onClick(View v) {
                            System.out.println("DOWNLOAD PRESSED");
                            viewHolder.downloadImageButton.setTag("downloaded");
                            tags.add(position, "downloaded");
                        }
                    });
            convertView.setTag(viewHolder);
        } else {
            viewHolder = (ViewHolder) convertView.getTag();
        }

        viewHolder.catlogTitle.setText(data.get(position));
        viewHolder.catlogTitle.setTypeface(regularDin);
        viewHolder.icon.setImageResource(R.drawable.cata);

        if (tags.get(position) == "downloaded") {
            downloadImageButton.setImageResource(R.drawable.icon_ok);
        } else {
            downloadImageButton.setImageResource(R.drawable.icon_download);
        }

        viewHolder.position = position;
        return convertView;
    } // close getView
}