Search code examples
androidlistviewandroid-arrayadapter

How to set onClick event for ImageView in ListView


I have a custom ListView that display song titles and each one contains two ImageView for adding to favorites and sharing song.

custom_listview.xml:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
   android:layout_width="match_parent"
   android:layout_height="wrap_content">

     <TextView android:id="@+id/song_title"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"/>

     <ImageView
         android:id="@+id/add_to_favorites"
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"/>

    <ImageView
        android:id="@+id/share"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"/>

</LinearLayout>

activity_main:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
   android:layout_width="match_parent"
   android:layout_height="match_parent" >

     <ListView
        android:id="@+id/listview"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

</RelativeLayout>

To fill the listview I need to use an ArrayAdapter:

public class Media_adapter extends ArrayAdapter<Media> {

                Context context;
                int layoutResourceId;
                Media data[] = null;


                public Media_adapter(Context context, int layoutResourceId, Media[] data) {
                    super(context, layoutResourceId, data);
                    this.layoutResourceId = layoutResourceId;
                    this.context = context;
                    this.data = data;
                }

                @Override
                public View getView(int position, View convertView, ViewGroup parent) {
                    View row = convertView;
                    MediaHolder holder = null;

                    if(row == null)
                    {
                        LayoutInflater inflater = ((Activity)context).getLayoutInflater();
                        row = inflater.inflate(layoutResourceId, parent, false);

                        holder = new MediaHolder();
                        holder.song_title = (TextView)row.findViewById(R.id.song_title);
                        holder.add_to_favorites = (ImageView)row.findViewById(R.id.add_to_favorites);
                        holder.share = (ImageView)row.findViewById(R.id.share);

                        row.setTag(holder);

                    }
                    else
                    {
                        holder = (MediaHolder)row.getTag();
                    }

                    Media media = data[position];
                    holder.song_title.setText(media.title);
                    holder.add_to_favorites.setImageResource(media.image_favorite);
                    holder.share.setImageResource(media.image_share);

                    return row;
                }

                class MediaHolder
                {
                    TextView song_title;
                    ImageView add_to_favorites, share;
                }

        }

Class Media:

package com...;

public class Media {

   public String title;
   public int image_favorite, image_share;

   public Media() {
       super();
   }

}

To playing a song, I have called setOnItemClickListener(...)

mylistview.setOnItemClickListener(new OnItemClickListener() {
        @Override
        public void onItemClick(AdapterView<?> av,
                                View view, int position, long l) {
            //code for playing song
        }
    });

Finally, I want to add onClick event for my two ImageView add_to_favorites and share used in item of Listview.


Solution

  • You should send an View.onClickListener inside your constructor of your adapter. Then assign it to the views that you interested to click on them and from there just implement the onClickListener in your activity/fragment.

    public class Media_adapter extends ArrayAdapter<Media> {
    
                Context context;
                int layoutResourceId;
                Media data[] = null;
                View.onClickListener listener; 
    
                public Media_adapter(Context context, int layoutResourceId, Media[] data,View.onClickListener) {
                    super(context, layoutResourceId, data);
                    this.layoutResourceId = layoutResourceId;
                    this.context = context;
                    this.data = data;
                    this.listener = listener;
                }
    
                @Override
                public View getView(int position, View convertView, ViewGroup parent) {
                    View row = convertView;
                    MediaHolder holder = null;
    
                    if(row == null)
                    {
                        LayoutInflater inflater = ((Activity)context).getLayoutInflater();
                        row = inflater.inflate(layoutResourceId, parent, false);
    
                        holder = new MediaHolder();
                        holder.song_title = (TextView)row.findViewById(R.id.song_title);
                        holder.add_to_favorites = (ImageView)row.findViewById(R.id.add_to_favorites);
                        holder.share = (ImageView)row.findViewById(R.id.share);
                        **holder.share.setTag(position);
                        holder.share.setOnClickListener(listener);**
                        row.setTag(holder);
    
                    }
                    else
                    {
                        holder = (MediaHolder)row.getTag();
                    }
    
                    Media media = data[position];
                    holder.song_title.setText(media.title);
                    holder.add_to_favorites.setImageResource(media.image_favorite);
                    holder.share.setImageResource(media.image_share);
    
                    return row;
                }
    
                class MediaHolder
                {
                    TextView song_title;
                    ImageView add_to_favorites, share;
                }
    
        }
    

    in your activity you will implement the View.onClicklistener

    public class MyActivity extends Activity implements View.onClickListener
    {
    
       when you create your adapter send **this** as the last parameter of the adapter constructor.
    
    
        public void onClick(View view) {
            switch (view.getId())
            { 
                case R.id.share:
    
                //here you need to retrieve the position of the item
                int position = (int)view.getTag();
                Media med = media[position];
                //here just use med where you want to use it.
    
                do the same thing for other componenets in your adapter layout. 
    
                break;
            }
    
    }
    

    A few things to notice:

    1. I recommend you to use recycleview (it's a bit more complicated but very useful to know) instead of using listview

    2. I didn't tested the code on my computer I just wrote it in my notepad, maybe you will get a few syntax errors

    update

    I created a simple project with the same functionality that you are looking for and everything is working correctly

    MainActivity

    public class MainActivity extends AppCompatActivity implements View.OnClickListener{
    
        private ListView mList;
        private Media_adapter mAdapter;
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
    
            mList = (ListView)findViewById(R.id.listview);
    
            Media[] data = new Media[5];
            for(int i=0;i<data.length;i++)
            {
                data[i] = new Media();
                data[i].title = "pos"+i;
                data[i].image_favorite = R.mipmap.ic_launcher;
                data[i].image_share = R.mipmap.ic_launcher;
            }
    
            mAdapter = new Media_adapter(this,R.layout.custom_listview,data,this);
            mList.setAdapter(mAdapter);
        }
    
        @Override
        public void onClick(View view) {
            int position;
            switch (view.getId())
            {
                case R.id.add_to_favorites:
                    position = (int) view.getTag(); Log.d("test", position + " add_to_favorites");
                    break;
                case R.id.share:
                    position = (int) view.getTag(); Log.d("test", position + " share");
                    break;
            }
    
        }
    }
    

    Media_adapter

    public class Media_adapter extends ArrayAdapter<Media>
    {
    
        Context                 context;
        int                     layoutResourceId;
        Media                   data[];
        View.OnClickListener    listener;
    
        public Media_adapter(Context context, int layoutResourceId, Media[] data, View.OnClickListener listener)
        {
            super(context, layoutResourceId, data);
            this.layoutResourceId = layoutResourceId;
            this.context = context;
            this.data = data;
            this.listener = listener;
        }
    
        @Override
        public View getView(int position, View convertView, ViewGroup parent)
        {
            View row = convertView;
            MediaHolder holder;
    
            if (row == null)
            {
                LayoutInflater inflater = ((Activity) context).getLayoutInflater();
                row = inflater.inflate(layoutResourceId, parent, false);
    
                holder = new MediaHolder();
                holder.song_title = (TextView) row.findViewById(R.id.song_title);
                holder.add_to_favorites = (ImageView) row.findViewById(R.id.add_to_favorites);
                holder.share = (ImageView) row.findViewById(R.id.share);
    
                holder.add_to_favorites.setTag(position);
                holder.add_to_favorites.setOnClickListener(listener);
                holder.share.setTag(position);
                holder.share.setOnClickListener(listener);
    
                row.setTag(holder);
    
            }
            else
            {
                holder = (MediaHolder) row.getTag();
            }
    
            Media media = data[position];
            holder.song_title.setText(media.title);
            holder.add_to_favorites.setImageResource(media.image_favorite);
            holder.share.setImageResource(media.image_share);
    
            return row;
        }
    
        class MediaHolder
        {
            TextView    song_title;
            ImageView   add_to_favorites, share;
        }
    }