首页 > 解决方案 > 从侦听器列表中删除侦听器

问题描述

我有一个将自定义侦听器添加到同一个触发事件的函数。

所以同一个事件可以触发多个监听器,这是可行的。我想要的是:如果我有 3 个听众(例如)能够只删除其中一个并让另外两个工作。

这是我添加事件的函数,它们在一个Map<String, CustomListener>变量中。

void addEventListener(String eventName, EventListener eventListener) {
    List<eventListener> eventListenerList = new ArrayList<>();

    if (eventListenerMap.containsKey(eventName)) {
        eventListenerList = eventListenerMap.get(eventName);
    }
    Objects.requireNonNull(eventListenerList).add(eventListener);
    eventListenerMap.put(eventName, eventListenerList);
}

这是我要删除的功能

void removeEventListener(String eventName, EventListener eventListener) {
    if (eventListenerMap.containsKey(eventName)) {
        List<InsEventListener> eventListenerList = eventListenerMap.get(eventName);
        assert eventListenerList != null;
        eventListenerList.remove(eventListener);

        eventListenerMap.put(eventName, eventListenerList);
    }
    else {
        Log.w("Remove Event Listener:", "Event not found");
    }
}

正如您在下图中看到的,它识别具有相同lamba 地址的同一个类,但它不会删除。

在此处输入图像描述

Obs:所有监听器在同一个地方的同一个函数中被调用

标签: javaandroidlistlistener

解决方案


那是因为eventListenerList.remove(eventListener.getClass());没有删除任何东西。您不应该通过他们的类来删除您的听众,而是通过索引或通过一种将它们与另一个区分开来的方法。
如果您检查了remove()返回值,您将得到 false,这意味着该参数不在该列表中。甲骨文文档

通常,可以通过两种方式从ArrayList(或通常任何列表)中删除对象,通过索引(remove(int))和通过对象(remove(Object))。参考这里

你需要做什么:

EventListener向您的类添加一个 equals(Object) 方法。这将使您能够eventListenerList.remove(eventListener)识别正确的对象。

我认为最简单的做法是向您的 Parent 类添加一个 name 或 id 属性,该属性在所有侦听器之间都是唯一的,并覆盖检查这些属性的 equals 。

您可以使用 Android Studio IDE 轻松生成equals(object)方法,按 Ctrl + O 并选择 equals 方法。

编辑:

我建议为您的听众处理 ID 的两个选项:

  1. 自己生成IDaddEventListener并返回给调用者,将监听器存储在映射而不是列表中,关键是ID。当有人想要移除一个监听器时,他会发送生成的 ID,然后您将从 Event 的 listeners 映射中移除它。
  2. 自己生成 IDaddEventListener并将其保存在EventListener其他任何人都无法更改的 ID 属性中。然后,要删除特定的侦听器,您只需要实现一个equals检查 ID 属性的方法。

推荐阅读