onItemSelected won't get called - android

Implementing the basic spinner example from the android website won't call call the onItemSelected. I haven't found a solution after reading around 25 answers in StackOverflow.
I can see the options on the spinner, but when I select one nothing happens. here is the code :
class MainActivity : AppCompatActivity(){
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val text = findViewById<TextView>(R.id.textView)
val spinner: Spinner = findViewById(R.id.spinner)
// Create an ArrayAdapter using the string array and a default spinner layout
ArrayAdapter.createFromResource(
this,
R.array.sources,
android.R.layout.simple_spinner_item
).also { adapter ->
// Specify the layout to use when the list of choices appears
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item)
// Apply the adapter to the spinner
spinner.adapter = adapter
}
class SpinnerActivity : Activity(), AdapterView.OnItemSelectedListener {
override fun onItemSelected(parent: AdapterView<*>, view: View, pos: Int, id: Long) {
Log.d("nothing", "happending")
when (parent.getItemAtPosition(pos).toString()){
"file 1" -> Log.d("Selection","file 1")
"file 2" -> Log.d("selection", "file 2")
else -> text.append("No match")
}
Toast.makeText(applicationContext,"Called made",Toast.LENGTH_LONG).show()
}
override fun onNothingSelected(parent: AdapterView<*>) {
// Another interface callback
}
}
}
}

Instead of creating the inner class SpinnerActivity, you should register the listener on the spinner:
spinner.onItemSelectedListener = object : AdapterView.OnItemSelectedListener {
override fun onItemSelected(parent: AdapterView<*>, view: View, pos: Int, id: Long) {
Log.d("nothing", "happending")
when (parent.getItemAtPosition(pos).toString()){
"file 1" -> Log.d("Selection","file 1")
"file 2" -> Log.d("selection", "file 2")
else -> text.append("No match")
}
Toast.makeText(applicationContext,"Called made",Toast.LENGTH_LONG).show()
}
override fun onNothingSelected(parent: AdapterView<*>) {
// Another interface callback
}
}

Related

How to retrieve the String of a selected item in spinner outside of onItemSelected method?

I need to retrieve the selected string in a spinner outside of the .onItemSelectedListener.
The dropdown menu contains "Each week, each month, each year" strings and I need to retrieve that selected item String in order use them in if conditionals outside of the function.
I've only seen people making Toasts in the onItemSelected function but this doesn't solve my problem.
This is my code:
val spinner = binding.tvAutoComplete
val powtarzanie = resources.getStringArray(R.array.powtarzanie)
val arrayAdapter = ArrayAdapter(requireContext(),
R.layout.dropdown_powtarzaj_item,
powtarzanie)
spinner.setAdapter(arrayAdapter)
spinner.onItemSelectedListener = object : AdapterView.OnItemSelectedListener {
override fun onItemSelected(
parent: AdapterView<*>?,
view: View?,
position: Int,
id: Long
) {
val itemText: String = parent?.getItemAtPosition(position).toString()
}
override fun onNothingSelected(parent: AdapterView<*>?) {
TODO("Not yet implemented")
}
}
One way and probably the most simple way to go about this is to define a global variable:
private var spinnerSelection: String? = null
and just change it in your onItemSelected implementation:
spinnerSelection = parent?.getItemAtPosition(pos).toString()
Example code showing the whole flow:
class MainActivity : AppCompatActivity(), AdapterView.OnItemSelectedListener {
private var spinnerSelection: String? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val spinner: Spinner = findViewById(R.id.spinner)
spinner.onItemSelectedListener = this
ArrayAdapter.createFromResource(
this,
R.array.numbers_array,
android.R.layout.simple_spinner_item
).also { adapter ->
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item)
spinner.adapter = adapter
}
val button: Button = findViewById(R.id.button)
button.setOnClickListener {
Log.d("MainActivity", "Currently selected item: $spinnerSelection")
}
}
override fun onItemSelected(parent: AdapterView<*>?, view: View?, pos: Int, id: Long) {
spinnerSelection = parent?.getItemAtPosition(pos).toString()
}
override fun onNothingSelected(parent: AdapterView<*>?) {
//TODO("Not yet implemented")
}
}

How to return value from function in Kotlin Android

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

spinner in kotlin not populating

my spinner is not populating
#RequiresApi(Build.VERSION_CODES.O)
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val adapter = ArrayAdapter.createFromResource(requireContext(), R.array.duration, android.R.layout.simple_spinner_item) as SpinnerAdapter
_binding?.duration?.adapter = adapter
_binding?.duration?.onItemSelectedListener = object :
AdapterView.OnItemSelectedListener {
#RequiresApi(Build.VERSION_CODES.O)
override fun onItemSelected(parent: AdapterView<*>,
view: View, position: Int, id: Long) {
val followeredata = followerData()
var followercount = followeredata.getcount(position)
Log.i("menu selected"," on item is selected")
}
override fun onNothingSelected(parent: AdapterView<*>?) {
TODO("Not yet implemented")
}
}
}
I have tried different methods of creating adapter but none of them are able to populate the spinner. but if I create them from XML:entries it works fine. how do I populate my spinner from code

I can't use the spinner function properly[kotlin]

I'm having trouble using the sendCommand function when the user change the spinner item to "Red":
class SetTrainingRouteActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_set_training_route)
val spinner: Spinner = findViewById(R.id.S24)
// Create an ArrayAdapter using the string array and a default spinner layout
ArrayAdapter.createFromResource(
this,
R.array.A24,
android.R.layout.simple_spinner_item
).also { adapter ->
// Specify the layout to use when the list of choices appears
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item)
// Apply the adapter to the spinner
spinner.adapter = adapter
}
S24.onItemSelectedListener = object : AdapterView.OnItemSelectedListener{
override fun onNothingSelected(parent: AdapterView<*>?) {
}
override fun onItemSelected(parent: AdapterView<*>?, view: View?, position: Int, id: Long) {
if (S24.equals("Red")) {
sendCommand("1000024")
}
}
}
}
private fun sendCommand(input: String) {
if (ControlActivity.arduino_bluetoothSocket != null) {
try{
ControlActivity.arduino_bluetoothSocket!!.outputStream.write(input.toByteArray())
} catch(e: IOException) {
e.printStackTrace()
}
}
}
}
<string-array name="A24">
<item>Off</item>
<item>Red</item>
<item>Green</item>
<item>Blue</item>
</string-array>
<Spinner
android:id="#+id/S24"
android:textColor="#color/text_matrix_cell"
android:layout_width="40dp"
android:layout_height="wrap_content"
android:entries="#array/A24" />
You are reading value in a wrong way. Below code will work
S24.onItemSelectedListener = object : AdapterView.OnItemSelectedListener{
override fun onNothingSelected(parent: AdapterView<*>?) {
}
override fun onItemSelected(parent: AdapterView<*>?, view: View?, position: Int, id: Long) {
val selectedItem = parent?.getItemAtPosition(position)
if (selectedItem?.equals("Red") == true) {
sendCommand("1000024")
}
}
}
What you are doing is comparing spinner instance to value "Red" which will never work, because they are not same.
You need to read the value using correct method and then compare them.

Android Kotlin onItemSelectedListener for spinner not working

I have a spinner with some items (strings).
I want to add the selected items to a list. I read online that I should use the onItemSelectedListenerrather than the onItemClickListener.
I implemented this but I don't know how to complete the step of adding it to the list.
class NewKitListActivity : AppCompatActivity() {
var spinnerArray = arrayOf("Dumbell", "Punching Bag", "Yoga Ball", "Skipping Rope")
//var spinnerArray = arrayOf(DataService.kitList)
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_new_kit_list)
val spinner = newKitItemSpinner
val spinnerArrayAdapter = ArrayAdapter<String>(this, android.R.layout.simple_spinner_dropdown_item, spinnerArray)
//selected item will look like a spinner set from XML
spinnerArrayAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item)
spinner.adapter = spinnerArrayAdapter
spinner.onItemSelectedListener = object : OnItemSelectedListener {
override fun onItemSelected(parent: AdapterView<*>, view: View, position: Int, id: Long) {
val selectedItem = parent.getItemAtPosition(position).toString()
if (selectedItem == "Add new category") {
// do your stuff
}
} // to close the onItemSelected
override fun onNothingSelected(parent: AdapterView<*>) {
}
}}}
Thanks
(in Kotlin)Use this code:
yourSpinner?.onItemSelectedListener = object : AdapterView.OnItemSelectedListener{
override fun onNothingSelected(parent: AdapterView<*>?) {
}
override fun onItemSelected(parent: AdapterView<*>?, view: View?, position: Int, id: Long) {
}
}
Thanks this is helpful for me, Its working fine !
daysSpinner.onItemSelectedListener = object : AdapterView.OnItemSelectedListener {
override fun onNothingSelected(parent: AdapterView<*>?) {
}
override fun onItemSelected(parent: AdapterView<*>?, view: View?, position: Int, id: Long) {
}
}
Add extension function
fun Spinner.selected(action: (position:Int) -> Unit) {
this.onItemSelectedListener = object : AdapterView.OnItemSelectedListener {
override fun onNothingSelected(parent: AdapterView<*>?) {}
override fun onItemSelected(parent: AdapterView<*>?, view: View?, position: Int, id: Long) {
action(position)
}
}
}
simple use
spinner.selected {
println(it) //selected position
}
string will not be able to check using '==' instead you need to use equals("string")
if (selectedItem.equals("Add new category")) {
// do your stuff
}
I implemented like this.
1. Create Empty Mutable List
2. Set onItemSelectedListner on spinner
3. When user select item add that to mutable list
Check my this answer for more info. It will help you: Android Koltin pass spinner values to mutable list
instead of:
var spinnerArray = arrayOf("Dumbell", "Punching Bag", "Yoga Ball", "Skipping Rope")
try
var spinnerArray = mutableListOf<String>("Dumbell", "Punching Bag", "Yoga Ball", "Skipping Rope")
just had the same situation when I was trying to get a sqlite tableĀ“s $_ID and populate the spinner with them
// Extends AdapterView.OnItemSelectedListener
class Dialogs : DialogFragment(), AdapterView.OnItemSelectedListener {}
//Somewhre in onCreate (I'm using databinding but you don't have to)
binding.spinnerDialogEstados.onItemSelectedListener = this
// then implement members...
override fun onItemSelected(parent: AdapterView<*>?, view: View?, position: Int, id: Long) {
TODO("Not yet implemented")
}
override fun onNothingSelected(parent: AdapterView<*>?) {
TODO("Not yet implemented")
}

Categories

Resources