如何在保留onClickListener的情况下向ListView添加菜单按钮?

huangapple go评论80阅读模式
英文:

How do I add a menu button to a listview, while keeping the onClickListener?

问题

我正在创建一个播放音乐的应用程序。

进入应用程序后,会显示一个包含所有播放列表的列表(ListView)。当在列表中点击项目(播放列表)时,它会打开播放列表并显示所有歌曲。所有这些都正常工作。

我现在想要在每个项目的右侧添加一个菜单。当点击菜单按钮时,我希望运行“代码 b”,而当点击项目时,我希望运行“代码 a”。以下是我创建项目的方式:

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));
        }
    });

}

以下是XML代码:

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

在ListView中的每个项目右侧添加一个按钮有没有简单的方法?我能想到的唯一方法是在ListView的项目中使用某种相对布局,然后在其中添加一个Button和一个ImageButton。

此菜单将用于诸如“删除播放列表”和“复制播放列表”之类的操作。

提前感谢您的帮助!

英文:

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&lt;Playlist&gt; playlists = getLists();

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

    ArrayList&lt;String&gt; playlistsText = new ArrayList&lt;&gt;();
    for (Playlist playlist : playlists)
        playlistsText.add(playlist.name);

    ArrayAdapter&lt;String&gt; adapter = new ArrayAdapter&lt;&gt;(mainActivity, android.R.layout.simple_list_item_1, playlistsText);
    listView.setAdapter(adapter);

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

}

Here is the XML code:

&lt;ListView
    android:id=&quot;@+id/playlist_list&quot;
    android:layout_width=&quot;match_parent&quot;
    android:layout_height=&quot;match_parent&quot;
    android:layout_centerHorizontal=&quot;true&quot;
    android:layout_centerVertical=&quot;true&quot;
    android:dividerHeight=&quot;1dp&quot; /&gt;

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!

答案1

得分: 0

感谢zgc7009在这个 Stack Overflow 帖子中的评论,我能够自定义列表中的元素,从而完全控制列表。下面我发布了代码,以便其他人可以重用它:

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;

    }
}

getView 函数是魔法发生的地方。我设置了列表项的文本,并为菜单按钮设置了 onClickListener。要为每个项应用点击事件,您可以继续使用标准的 listView.setOnClickListener 函数!

以下是 list_item.xml 的 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>

要应用此内容,以下是我用于测试的代码(您可以为每个项更改监听器):

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);
        // 播放歌曲
    }
});
英文:

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&lt;String, View.OnClickListener&gt; data;
private static LayoutInflater inflater = null;
public ListAdapter(Context context, Map&lt;String, View.OnClickListener&gt; 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:

&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&gt;
&lt;RelativeLayout xmlns:android=&quot;http://schemas.android.com/apk/res/android&quot;
android:layout_width=&quot;match_parent&quot;
android:layout_height=&quot;match_parent&quot;&gt;
&lt;include
android:id=&quot;@+id/item_title&quot;
layout=&quot;@android:layout/simple_list_item_1&quot; /&gt;
&lt;TextView
android:id=&quot;@+id/item_menu&quot;
android:layout_width=&quot;wrap_content&quot;
android:layout_height=&quot;wrap_content&quot;
android:layout_alignParentEnd=&quot;true&quot;
android:layout_marginEnd=&quot;10dp&quot;
android:layout_centerVertical=&quot;true&quot;
android:paddingHorizontal=&quot;10dp&quot;
android:text=&quot;&amp;#8942;&quot;
android:textAppearance=&quot;@style/TextAppearance.AppCompat.Large&quot; /&gt;
&lt;/RelativeLayout&gt;

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(), &quot;Menu Button&quot;, Toast.LENGTH_SHORT).show();
}
};
Map&lt;String, View.OnClickListener&gt; map = new LinkedHashMap&lt;&gt;();
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&lt;?&gt; parent, View view, int position, long id) {
Song song = songs.get(position);
// Play song
}
});

huangapple
  • 本文由 发表于 2020年5月5日 10:20:15
  • 转载请务必保留本文链接:https://go.coder-hub.com/61604654.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定