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.
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:
I recommend you to use recycleview (it's a bit more complicated but very useful to know) instead of using listview
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;
}
}