Change image on click in custom listview Android

10,551

Solution 1

Adapter based views like ListView recycles its views to save resources. During scrolls, ListView will recycle views that are no more visible. This post by Lucas is a great place to learn more about its working: http://lucasr.org/2012/04/05/performance-tips-for-androids-listview/

So registering onClick in your getView() method might not be a very good idea. Instead use the setOnItemClickListener() method on your ListView.

To accomplish what you're trying to do, you can do this:

Edit: Updated my code as per your comment.

mYourListView..setOnItemClickListener(new OnItemClickListener() {

        @Override
        public void onItemClick (AdapterView<?> parent, View view, int position, long id) {
            Toast.makeText(context, "Item #" + position + " clicked", Toast.LENGTH_SHORT).show();

            // here, "position" is the position of your item and "id" is your
            // item's id in your data set.

            // mLastClickedPosition is a member field of type long which 
            // stores the position of the most recently clicked item, 
            // initially set to -1
            if(mLastClickedPosition != -1){
                  // do something to pause the item in your list at this position
            }

            // next, update mLastClickedPosition
            mLastClickedPosition = position

            // find the image in your view and update it
            if(position==0){
                  ImageView imageView = view.findViewById(R.id.your_image);
                  imageView.setImageResource(R.drawable.pause);
            }

            // play audio
            AudioListner.playRecord(position);

        }
    });

Solution 2

In your posted code you have ImageView image which belongs to your adapter, and therefore "global" to your list.

Instead, what you seem to want is to have onClick handler for each individual list item.

For this I recommend you to implement OnItemClickListener for you listView,

or alternatively you could change your onClick code to something like :

    // set onClick for each img in the list
    holder.img.setOnClickListener(new OnClickListener() { 

        @Override
        public void onClick(View v) {
            ((ImageView) v).setImageResource(R.drawable.pause);
        }
    });

and don't forget to initialize holder.img as it is currently commented out.

Share:
10,551
zek
Author by

zek

Updated on June 04, 2022

Comments

  • zek
    zek almost 2 years

    In my custom listview I want to change Image when the image is clicked. But currently when I click on Image, last row image is changed not the one on which I clicked. My customAdapter classis below:

    package com.zek.androidvoicechanger;
    
    import java.util.List;
    
    import org.w3c.dom.Text;
    
    import android.app.Activity;
    import android.content.Context;
    import android.media.Image;
    import android.view.LayoutInflater;
    import android.view.View;
    import android.view.View.OnClickListener;
    import android.view.ViewGroup;
    import android.widget.ArrayAdapter;
    import android.widget.Button;
    import android.widget.CompoundButton;
    import android.widget.CompoundButton.OnCheckedChangeListener;
    import android.widget.ImageView;
    import android.widget.RadioButton;
    import android.widget.TextView;
    import android.widget.Toast;
    
    public class CustomAdapter extends ArrayAdapter<Items> {
    
        Context context;
        ImageView image ;
    
    
    //  int[] Radio = { R.drawable.play, R.drawable.pause };
    
        public CustomAdapter(Context context, int resourceId, List<Items> items) {
            super(context, resourceId, items);
            this.context = context;
        }
    
        private class ViewHolder {
            // ImageView imageView;
    
            TextView txtTitle;
    //      ImageView img;
    
        }
    
        public View getView(final int position, View convertView,
                final ViewGroup parent) {
    
            ViewHolder holder = null;
    
            Items rowItem = getItem(position);
    
            LayoutInflater mInflater = (LayoutInflater) context
                    .getSystemService(Activity.LAYOUT_INFLATER_SERVICE);
    
            if (convertView == null) {
                convertView = mInflater.inflate(R.layout.custom_list, null);
                holder = new ViewHolder();
    
                holder.txtTitle = (TextView) convertView
                        .findViewById(R.id.textView1);
    //          holder.img = (ImageView) convertView.findViewById(R.id.imageView2);
                image = (ImageView) convertView.findViewById(R.id.imageView2);
            //  holder.rdo = (RadioButton) convertView.findViewById(R.id.radioButton1);
                convertView.setTag(holder);
            } else
                holder = (ViewHolder) convertView.getTag();
    
            holder.txtTitle.setText(rowItem.getTitle());
    
            image.setImageResource(rowItem.getImageId());
            image.setOnClickListener(new OnClickListener() {
    
                @Override
                public void onClick(View v) {
                    Toast.makeText(context, "image clicked", 1000).show();
                    if(position==0){
                    image.setImageResource(R.drawable.pause);
                    }
                    AudioListner.playRecord(position);
    
                }
            });
    
    
    
        //holder.rdo.setTag(position);
    //      holder.rdo.setOnCheckedChangeListener(new OnCheckedChangeListener() {
    //          
    //          @Override
    //          public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
    //
    //          
    //              
    //          }
    //      });
    
    //      rdo.setOnClickListener(new OnClickListener() {
    //
    //          @Override
    //          public void onClick(View v) {
    //
    //              
    //              if(position==0){
    //                  rdo.indexOfChild(findViewById(isEnabled(position)));
    //                  Toast.makeText(context, "image clicked", 1000).show();
    //                  rdo.setBackgroundResource(R.drawable.pause);
    //                  AudioListner.playRecord(position);
    //                  
    //              }
    //              
    //              
    //              
    //              if (rdo.isClickable()) {
    //                  rdo.setBackgroundResource(R.drawable.pause);
    //                  Toast.makeText(context, "image clicked", 1000).show();
    //
    //                  //Radio[1] = 1;
    //                  AudioListner.playRecord(position);
    //                  
    //              } else {
    //              //  rdo.setBackgroundResource(R.drawable.play);
    //                  Toast.makeText(context, "image not clicked", 1000).show();
    //
    //              }
    ////
    //          }
    //      });
    
            return convertView;
        }
    
    }
    

    Any help will be appreciated.

  • Saket
    Saket about 10 years
    Maintaining a separate data structure for tracking clicked row items is not a very good approach.
  • zek
    zek about 10 years
    thank you all of u guyz it was real helpful. it is working but i have one real problem that is i wana change image of each imageview in list it that is clicked and want rest all of them in previous state.. example play and pause .if i play one item it icon is changed to pause icon and when i click other one it also changed in pause state what i what is one at a time to play and the rest in pause state..how can i handle that ..?
  • Saket
    Saket about 10 years
    @zek, that's pretty easy to do. Simply use an extra member field to track the position of last clicked item. See my edit.