如何在保留 onClickListener 的同时将菜单按钮添加到列表视图?

Posted

技术标签:

【中文标题】如何在保留 onClickListener 的同时将菜单按钮添加到列表视图?【英文标题】:How do I add a menu button to a listview, while keeping the onClickListener? 【发布时间】:2020-08-19 14:42:23 【问题描述】:

我正在创建一个应用来播放音乐。

进入应用程序后,会显示所有播放列表的列表(ListView)。单击 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_
    android:layout_
    android:layout_centerHorizontal="true"
    android:layout_centerVertical="true"
    android:dividerHeight="1dp" />

有没有一种简单的方法可以在 ListView 中每个项目的右侧添加某种按钮?我能想到的唯一方法是以某种方式使用相对布局作为 ListView 中的项目,我可以使用 Button 和 ImageButton 填充它。

此菜单可用于“删除播放列表”和“复制播放列表”等操作。

提前致谢!

【问题讨论】:

使用自定义视图而不是标准列表项视图。 @zgc7009 我从来没有听说过CustomView ...你能发布一个我如何应用它的代码示例吗? :) 改用RecyclerView - simplifiedcoding.net/… 如果你谷歌自定义列表视图项,有很多例子。 ***.com/questions/15832335/… @zgc7009 堆栈溢出链接效果很好。如果您将其作为答案,我会将其标记为正确。感谢您的帮助! 【参考方案1】:

感谢zgc7009 对this 堆栈溢出的评论,我能够自定义列表中的元素,让我能够完全控制列表。下面我把代码贴出来,方便其他人重复使用:

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_
    android:layout_>

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

    <TextView
        android:id="@+id/item_menu"
        android:layout_
        android:layout_
        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);
        // Play song
    
);

【讨论】:

以上是关于如何在保留 onClickListener 的同时将菜单按钮添加到列表视图?的主要内容,如果未能解决你的问题,请参考以下文章

在 listview Android 1.6 中同时使用 onClickListener 和 onLongClickListener

Listview ArrayAdapter 自定义项 onClickListener 仅第一次工作

如何在保留通知中心的同时清除徽章编号

Android中View类OnClickListener和DialogInterface类OnClickListener冲突解决办法

如何在 Kotlin 中实现 OnClickListener 接口? [复制]

如何在 Android 中的 RadioButton 上设置 OnClickListener?