Home > Back-end >  How to return value from function in Kotlin Android
How to return value from function in Kotlin Android

Time:08-12

In my application I want used extension function and I want return String!
I set return value from function and I write below codes, but show me empty value!
My Extension function code :

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
}

When show logs in logcat, first show 2 then show 1 !
Logs :

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

Why first call log 2 then call log 1 ?!
I used this func in fragment and for this when used this in fragment show me empty value! How can I fix it?

CodePudding user response:

Change your extension function like below

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

Then in Activity or fragment

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

CodePudding user response:

Use typealias for callback

 typealias OnSelectedCategory = (value: String) -> Unit

Update your method with callback

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

call with spinner

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

CodePudding user response:

Here's the direct answer to your question about why the logs are not in the order you expected:

Your listener is called repeatedly in the future each time items are selected. The current function that creates this listener doesn't wait for any of that to happen. It sets up the listener and returns right away before any items have been selected. It wouldn't make sense for it to wait, because then your app would be frozen, waiting for this function to return because the user has to select an item before the listener is called. But if your app was frozen, then the user could never make a selection, so it would be frozen forever.

The other answers show how you might fix it, but it depends what you're trying to do. It doesn't logically make sense for this function to return a String, because you don't know how many times in the future the user is going to select an item. It could be zero times, one time, or many times.

  • Related