繁体   English   中英

如何从 Kotlin Android 中的 function 返回值

[英]How to return value from function in Kotlin Android

在我的应用程序中,我想使用扩展function 并且我想返回String
我从 function 设置返回值,然后写下面的代码,但显示值!
我的扩展 function 代码:

fun Spinner.setupListWithAdapter(list: MutableList<String>): String {
    var itemSelected = ""
    val adapter = ArrayAdapter(context, android.R.layout.simple_spinner_item, list)
    adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item)
    this.adapter = adapter
    this.onItemSelectedListener = object : AdapterView.OnItemSelectedListener {
        override fun onItemSelected(p0: AdapterView<*>?, p1: View?, p2: Int, p3: Long) {
            itemSelected = list[p2]
            Log.e("categoryLog","1 : " + itemSelected)
        }
        override fun onNothingSelected(p0: AdapterView<*>?) {
        }
    }
    Log.e("categoryLog","2 : " +itemSelected)
    return itemSelected
}

当 show 登录logcat时,先显示 2 再显示 1 !
日志:

2022-08-12 14:49:59.261 12074-12074/com.my.app E/categoryLog: 2 : 
2022-08-12 14:49:59.310 12074-12074/com.my.app E/categoryLog: 1 : Movies

为什么先调用log 2然后调用log 1 ?!
我在片段中使用了这个函数,并且在fragment中使用这个函数时显示值? 我该如何解决?

更改您的扩展 function 如下所示

fun Spinner.setupListWithAdapter(list: MutableList<String>,callback: String -> Unit){
        var itemSelected = ""
        val adapter = ArrayAdapter(context, android.R.layout.simple_spinner_item, list)
        adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item)
        this.adapter = adapter
        this.onItemSelectedListener = object : AdapterView.OnItemSelectedListener {
            override fun onItemSelected(p0: AdapterView<*>?, p1: View?, p2: Int, p3: Long) {
                itemSelected = list[p2]
                callback(itemSelected)
                Log.e("categoryLog","1 : " + itemSelected)
            }
            override fun onNothingSelected(p0: AdapterView<*>?) {
            }
        }
        Log.e("categoryLog","2 : " +itemSelected)
       
    }

然后在 Activity 或 Fragment

spinner.setupListWithAdapter(list){
 // It will invoked when something is selected from spinner
}

使用 typealias 进行回调

 typealias OnSelectedCategory = (value: String) -> Unit

使用回调更新您的方法

fun Spinner.setupListWithAdapter(list: MutableList<String>,listener : OnSelectedCategory) {
    var itemSelected = ""
    val adapter = ArrayAdapter(context, android.R.layout.simple_spinner_item, list)
    adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item)
    this.adapter = adapter
    this.onItemSelectedListener = object : AdapterView.OnItemSelectedListener {
        override fun onItemSelected(p0: AdapterView<*>?, p1: View?, p2: Int, p3: Long) {
            itemSelected = list[p2]
            Log.e("categoryLog","1 : " + itemSelected)
               listener.invoke(itemSelected)
        }
        override fun onNothingSelected(p0: AdapterView<*>?) {
        }
    }
    Log.e("categoryLog","2 : " +itemSelected)
   
}

用微调器调用

spinner.setupListWithAdapter(list){ value ->
 Log.e("categoryLog","2 : " +value)
}

这是您关于为什么日志不符合您预期的顺序的问题的直接答案:

以后每次选择项目时都会重复调用您的侦听器。 创建此侦听器的当前 function 不会等待任何这些发生。 它设置侦听器并在选择任何项目之前立即返回。 等待是没有意义的,因为那样您的应用程序将被冻结,等待此 function 返回,因为用户必须在调用侦听器之前 select 一个项目。 但是,如果您的应用程序被冻结,那么用户将永远无法进行选择,因此它将永远被冻结。

其他答案显示了您如何解决它,但这取决于您要做什么。 这个 function 返回一个字符串在逻辑上是没有意义的,因为你不知道用户在未来多少次去 select 一个项目。 它可能是零次、一次或多次。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM