Home > Software design >  How to retrieve the value of a variable modified in the onItemSelected function with Kotlin in Andro
How to retrieve the value of a variable modified in the onItemSelected function with Kotlin in Andro

Time:01-03

I need to retrieve the value of a variable modified in the onItemSelected function using a when. Here is what i've done :

(...)

private var i: Int = 0

override fun onCreate(savedInstanceState: Bundle?) {
    (...)

    categorySpinner.onItemSelectedListener = object : AdapterView.OnItemSelectedListener {
        @SuppressLint("SetTextI18n")
        override fun onNothingSelected(parent: AdapterView<*>?) {

        }

        override fun onItemSelected(parent: AdapterView<*>?, view: View?, position: Int, id: Long) {
            category = categories[position]

            when (category) {
                "Décès" -> i = 1
                "Habitat" -> i = 2
            }
        }
    }

    binding.tvtest.text = i.toString()

    val acteSpinner: Spinner = binding.acteCreatingSpinnerActes
    when (i) {
        1 -> {
            val adapter = ArrayAdapter(this, android.R.layout.simple_spinner_item, actes[actes.indexOf(deces)])
            adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item)
            acteSpinner.adapter = adapter
            acte = acteSpinner.selectedItem.toString()
        }
        2 -> {
            val adapter = ArrayAdapter(this, android.R.layout.simple_spinner_item, actes[actes.indexOf(habitat)])
            adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item)
            acteSpinner.adapter = adapter
            acte = acteSpinner.selectedItem.toString()
        }
    }
}

}

i've tried to retrieve the value of variable i in a layout and i got i = 0. i want to get the value obtained in the onItemSelected function

CodePudding user response:

  1. Should not use hard-string in code: "Décès", "Habitat"
  2. No need i variable. Just using position:
when (position) {
        0 -> {
            val adapter = ArrayAdapter(this, android.R.layout.simple_spinner_item, actes[actes.indexOf(deces)])
            adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item)
            acteSpinner.adapter = adapter
            acte = acteSpinner.selectedItem.toString()
        }
        1 -> {
            val adapter = ArrayAdapter(this, android.R.layout.simple_spinner_item, actes[actes.indexOf(habitat)])
            adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item)
            acteSpinner.adapter = adapter
            acte = acteSpinner.selectedItem.toString()
        } }

CodePudding user response:

There is no problem with changing a class member inside the callback, but your code as-written doesn't work because the callback doesn't run immediately - it runs later when the user clicks on an item.

It appears you want the adapter for acteSpinner to change between two different sets of data when you select something in categorySpinner. You can do that by modifying the data in the adapter directly. Here's an example of how you could do that.

// You could make adapter a class member, but it is not necessary
// for this example
//private lateinit var adapter: ArrayAdapter<String>

override fun onCreate(savedInstanceState: Bundle?) {
    //...
    
    val binding = ...
    
    val adapter = ArrayAdapter(this, android.R.layout.simple_spinner_item)
    adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item)
    acteSpinner.adapter = adapter
    
    // Initially set the adapter to show list one
    adapter.addAll(firstList)
    binding.tvtest.text = "List One"
    
    categorySpinner.onItemSelectedListener = object : AdapterView.OnItemSelectedListener {
        @SuppressLint("SetTextI18n")
        override fun onNothingSelected(parent: AdapterView<*>?) {

        }

        override fun onItemSelected(parent: AdapterView<*>?, view: View?, position: Int, id: Long) {
            category = categories[position]
            // POINT B - Inside the callback. This code does not
            // run immediately, it runs later when an 
            // item is selected

            when (category) {
                "Décès" -> {
                    adapter.clear()
                    adapter.addAll(listOne)
                    adapter.notifyDataSetChanged()
                    binding.tvtest.text = "List One"
                }
                "Habitat" -> {
                    adapter.clear()
                    adapter.addAll(listTwo)
                    adapter.notifyDataSetChanged()
                    binding.tvtest.text = "List Two"
                }
            }
        }
    }

    // POINT A - Outside the callback
    //...
}

Note the "Point A" and "Point B" comments - in this code "Point A" will run first, even though "Point B" is on an earlier line. If you try to do something at "Point A" using a variable you modified at "Point B" it will not work.

  • Related