【问题标题】:How to set up a listener for a variable in Kotlin如何在 Kotlin 中为变量设置监听器
【发布时间】:2019-06-16 06:03:07
【问题描述】:

如何设置接口侦听器以检测 Kotlin 中的变量更改。我在 Java 中成功实现了以下功能,但在 Kotlin 中遇到了问题:

界面:

public interface InterfaceRefreshList
    {
    public void refreshListRequest();
    }

包含监听器的类:

public class SignalChange
    {
    private static boolean refreshListSwitch;
    private static List<InterfaceRefreshList> refreshListListeners = new ArrayList<>();
    public static void setRefreshList(boolean value)
    {
    refreshListSwitch = value;
    for(InterfaceRefreshList l : refreshListListeners)
        l.refreshListRequest();
    }
    public static void addRefreshListListener(InterfaceRefreshList l)
        {
        refreshListListeners.add(l);
        }
    }

监听器正在监听的类:

public class FragmentBrowse extends Fragment
{
    public FragmentBrowse() /// Constructor
        {
        SignalChange.addRefreshListListener(() -> refreshList());
        }
    refreshList()
    {
    // do something
    }
}

发出改变的信号:

SignalChange.setRefreshList(true);

我可以设置接口和信号类:

class SignalChange
{
    private var refreshListSwitch: Boolean = false
    var setSwitch: Boolean
        get() = refreshListSwitch
        set(value)
        {
            refreshListSwitch = value
        }

    private var refreshListListeners = ArrayList<InterfaceRefreshPersonsList>()
    fun sendRefreshSignal()
    {
        for(l in refreshListListeners) l.refreshPersonsList()
    }

    fun addRefreshListListener(l: InterfaceRefreshPersonsList)
    {
        refreshListListeners.add(l)
    }

}

但我无法在 FragmentBrowse 类中设置监听器。片段类不允许构造函数。

【问题讨论】:

  • 您遇到了哪些问题?为什么不简单地在 Java 代码上运行 Java 到 Kotlin 的转换器?
  • 转换器并非如此简单地工作。例如,我必须做的私有变量的静态设置器: private var refreshListSwitch: Boolean = false var setSwitch: Boolean get() = refreshListSwitch set(value) { refreshListSwitch = value }
  • 你为什么要这么做?这看起来完全没有必要。无论如何,您没有回答您在使用 Kotlin 代码时遇到的具体问题。
  • 查看修改后的代码
  • 添加监听的代码需要放在initializer block中。 IntelliJ IDEA 中内置的 Java 到 Kotlin 转换器能够自动执行此转换。

标签: android kotlin listener


【解决方案1】:

KOTLIN中监听变量的简单方法

private var myVariableName by Delegates.observable(0) { property, oldValue, newValue ->
             Log.d(TAG,"New Value $newValue")
             Log.d(TAG,"Old Value $oldValue")
        }

更多信息请阅读https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.properties/-delegates/

【讨论】:

  • 谢谢。如何为 myVariableName 分配类型?我试过myVariableName: String by Delegates.... 还是不行
  • 哦,我明白了。将 0 分配为初始值会自动使 myVariableName 成为 Int。所以我们应该为字符串做myVariableName by Delegates.observable("Initial Text")
【解决方案2】:

您可以使用内置的 Kotlin 委托,例如:

object SignalChange {
    var refreshListListeners = ArrayList<InterfaceRefreshList>()

    // fires off every time value of the property changes
    var property1: String by Delegates.observable("initial value") { property, oldValue, newValue ->
        // do your stuff here
        refreshListListeners.forEach { 
            it.refreshListRequest()
        }
    }
}

interface InterfaceRefreshList {
    fun refreshListRequest()
}

像这样添加监听器:

SignalChange.refreshListListeners.add(object : InterfaceRefreshList {
    override fun refreshListRequest() {
        refreshList()
    }
})

你可以使用lambda

object SignalChange {
    var refreshListListeners = ArrayList<() -> Unit>()

    // fires off every time value of the property changes
    var property1: String by Delegates.observable("initial value") { property, oldValue, newValue ->
        // do your stuff here
        refreshListListeners.forEach {
            it()
        }
    }
}

添加监听器只需调用:

SignalChange.refreshListListeners.add(::refreshList)
//or
SignalChange.refreshListListeners.add { refreshList() }

fun refreshList() {

}

【讨论】:

  • 通过发布的 Java 代码,我能够从程序中的任何位置发出更改信号。 Delegates.observable 能做到吗?
  • 我编辑了我的答案。当您将值设置为 property1 时,Delegates.observable 会触发并在每个侦听器上调用 refreshListRequest()
  • 这似乎与 fun sendRefreshSignal() for(l in refreshListListeners) l.refreshPersonsList() 相同,但我遇到的问题是如何调用: fun addRefreshListListener(l: InterfaceRefreshPersonsList) refreshListeners.add( l) 来自 FragmentBrowse 类
  • 看来您需要将SignalChange 实现为Singleton。然后你就可以像这样添加监听器了。我已经编辑了我的答案,现在SignalChange Singleton
  • 您给了我们 2 个答案,这很棒。一个比另一个更好吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-01-25
  • 1970-01-01
  • 2022-01-22
  • 2021-09-08
  • 1970-01-01
  • 2021-01-23
相关资源
最近更新 更多