0

I am creating a app to play music.

Upon entering the app, a list (ListView) of all the playlists show. When clicking on the item (playlist) in the ListView, it opens the playlist and displays all the songs. All of this works.

I am now trying to add a menu to the right side of each item. When clicking on the menu button I want "code b" to run, while clicking on the item, I want "code a" to run. Here is how I create the items:

public static void createList(final MainActivity mainActivity, ListView listView) {

    final ArrayList<Playlist> playlists = getLists();

    playlists.sort(new Comparator<Playlist>() {
        @Override
        public int compare(Playlist playlist1, Playlist playlist2) {
            return playlist1.name.compareTo(playlist2.name);
        }
    });

    ArrayList<String> playlistsText = new ArrayList<>();
    for (Playlist playlist : playlists)
        playlistsText.add(playlist.name);

    ArrayAdapter<String> adapter = new ArrayAdapter<>(mainActivity, android.R.layout.simple_list_item_1, playlistsText);
    listView.setAdapter(adapter);

    listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
        @Override
        public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
            new PlaylistFragment(mainActivity, playlists.get(position));
        }
    });

}

Here is the XML code:

<ListView
    android:id="@+id/playlist_list"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_centerHorizontal="true"
    android:layout_centerVertical="true"
    android:dividerHeight="1dp" />

Is there an easy way to add some sort of button to the right of each item in the ListView? The only way I can think is to use a relative layout somehow as the items in the ListView, which I can populate with a Button and ImageButton.

This menu would be used for things like "Remove Playlist" and "Copy Playlist".

Thanks in advance!

mega12345mega
  • 503
  • 1
  • 6
  • 17
  • Use a custom view instead of the standard list item view. – zgc7009 May 05 '20 at 02:22
  • @zgc7009 I have never heard of a CustomView ... could you post a code example of how I could apply this? :) – mega12345mega May 05 '20 at 02:24
  • Use a `RecyclerView` instead - https://www.simplifiedcoding.net/create-options-menu-recyclerview-item-tutorial/ – HB. May 05 '20 at 05:41
  • 1
    There are lots of examples if you Google custom list view item. https://stackoverflow.com/questions/15832335/android-custom-row-item-for-listview – zgc7009 May 05 '20 at 12:11
  • @zgc7009 The stack overflow link worked great. If you make it an answer, I will mark it as correct. Thanks for your help! – mega12345mega May 05 '20 at 20:54
  • No sweat. If you want you can type out what you did as an example and accept your own answer so someone can have a solution to the problem when they get here. Or if you feel the other answer suffices you can close this so that it doesn't end up as redirect clutter. Glad it worked. – zgc7009 May 05 '20 at 22:39

1 Answers1

0

Thanks to zgc7009's comment for this stack overflow, I was able to customize what element was inside the list, allowing me to take full control over the list. Below I have posted the code, so other people can reuse it:

public class ListAdapter extends BaseAdapter {

    Context context;
    Map<String, View.OnClickListener> data;
    private static LayoutInflater inflater = null;

    public ListAdapter(Context context, Map<String, View.OnClickListener> data) {
        this.context = context;
        this.data = data;

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

    @Override
    public int getCount() {
        return data.size();
    }

    @Override
    public Object getItem(int position) {
        return data.keySet().toArray()[position];
    }

    @Override
    public long getItemId(int position) {
        return position;
    }

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

        View view = convertView;
        if (view == null)
            view = inflater.inflate(R.layout.list_item, null);

        TextView title = view.findViewById(R.id.item_title);
        title.setText((String) data.keySet().toArray()[position]);

        TextView menu = view.findViewById(R.id.item_menu);
        menu.setOnClickListener((View.OnClickListener) data.values().toArray()[position]);

        return view;

    }
}

The getView function is where the magic happens. I set the text for the list item, and set the onClickListener for the menu button. To apply the click event for each item, you can continue using the standard listView.setOnClickListener function!

Here is the XML for list_item.xml:

<?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">

    <include
        android:id="@+id/item_title"
        layout="@android:layout/simple_list_item_1" />

    <TextView
        android:id="@+id/item_menu"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentEnd="true"
        android:layout_marginEnd="10dp"
        android:layout_centerVertical="true"
        android:paddingHorizontal="10dp"
        android:text="&#8942;"
        android:textAppearance="@style/TextAppearance.AppCompat.Large" />

</RelativeLayout>

To apply this, here is the code I used for testing (you would change the listener to be different for each item):

View.OnClickListener listener = new View.OnClickListener() {
    @Override
    public void onClick(View view) {
        Toast.makeText(view.getContext(), "Menu Button", Toast.LENGTH_SHORT).show();
    }
};

Map<String, View.OnClickListener> map = new LinkedHashMap<>();
for (Playlist.Song song : songs)
    map.put(song.getText(), listener);

ListAdapter adapter = new ListAdapter(mainActivity, map);
listView.setAdapter(adapter);

listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
    @Override
    public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
        Song song = songs.get(position);
        // Play song
    }
});
mega12345mega
  • 503
  • 1
  • 6
  • 17