Cannot set OnItemClickListener for spinner in android
Asked Answered
M

4

5

In a customized RecyclerView.Adapter<CustomAdapter.ViewHolder>, I set an adapter for a spinner and found that the value of my spinner isn't change after selection, so I tried to add an OnItemClickListener on my spinner:

override fun onBindViewHolder(viewHolder: ViewHolder, position: Int) {

    // The selectable items of the spinner is dynamically generated from getItems() function
    val selectableItems: List<String> = getItems()

    val spinnerAdapter = ArrayAdapter<String>(this.context, androi.R.layout.simple_spinner_item)
    spinnerAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item)
    spinnerAdapter.addAll(selectableItems)

    viewHolder.mySpinner.adapter = spinnerAdapter

    // the error occurs on the following line:
    viewHolder.mySpinner.onItemClickListener = AdapterView.OnItemClickListener { adapterView, view, i, l ->
        adapterView.setSelection(i)
    }

    viewHolder.mySpinner.setSelection(origionSelectedPosition)
}

I didn't get any warning or error while compiling, however during run time, I got a RuntimeException said that setOnItemClickListener cannot be used with a spinner. It is kind of strange. Did I do anything wrong in my code? Or does anyone know why my spinner didn't change with the corresponding selection?

Further description for Kotlin solution:

I had ever tried to use onItemSelectedListener but failed to find a suitable way to use it in kotlin. But finally! The following code solved my problem:

    viewHolder.mySpinner.onItemSelectedListener = object : AdapterView.OnItemSelectedListener {

        override fun onItemSelected(parent: AdapterView<*>, view: View, pos: Int, id: Long) {

        }

        override fun onNothingSelected(parent: AdapterView<out Adapter>?) {

        }

    }
Moonstone answered 21/4, 2016 at 6:37 Comment(6)
yes.. you are suppose to use spinner.onItemSelectedListenerBatman
Possible duplicate of I have an error: setOnItemClickListener cannot be used with a spinner, what is wrong?Epigone
Check this solution: https://mcmap.net/q/181400/-i-have-an-error-setonitemclicklistener-cannot-be-used-with-a-spinner-what-is-wrongCourtmartial
Thanks for those reference. It's so strange that either java or kotlin doesn't disable the onClidk function during compile time though.Moonstone
Hey, I had a similar problem. But now even when I have the right code my listener is not firing. Could you confirm it worked for you? If so, maybe you could look at my Question, too, to see if you can see any problems with it. Here it isEddington
@JoeSovcik sorry for that I was off for months until now seeing your comment. Seems that you've found your problem. Congrats!Moonstone
S
7

Use setOnItemSelectedListener instead of onItemClickListener.

viewHolder.mySpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
    @Override
    public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {

    }

    @Override
    public void onNothingSelected(AdapterView<?> parent) {

    }
});
Swagsman answered 21/4, 2016 at 6:40 Comment(3)
That's where I had also stuck in... Actually I had tried to use this, however since I wrote in kotlin, I fail to find an appropriate syntax which the compiler doen't complain... I'll append my code in kotlin for this in my question later.Moonstone
Oh I just found a way to write in in Kotlin! thanks a lot!Moonstone
I've already added it in my original question. Maybe I should also post it as a new answer.Moonstone
M
13

Following sasikumar's answer, I solved it in kotlin with the following code:

viewHolder.mySpinner.onItemSelectedListener = object : AdapterView.OnItemSelectedListener {

    override fun onItemSelected(parent: AdapterView<*>, view: View, pos: Int, id: Long) {

    }

    override fun onNothingSelected(parent: AdapterView<out Adapter>?) {

    }

}
Moonstone answered 21/4, 2016 at 7:11 Comment(1)
Although sasikumar's answer helped you get there, I'm sure you should accept your own answer as a solution and save everyone the time in the future. I have tried so many ways but didn't know of adding "object :" in KotlinBambi
S
7

Use setOnItemSelectedListener instead of onItemClickListener.

viewHolder.mySpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
    @Override
    public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {

    }

    @Override
    public void onNothingSelected(AdapterView<?> parent) {

    }
});
Swagsman answered 21/4, 2016 at 6:40 Comment(3)
That's where I had also stuck in... Actually I had tried to use this, however since I wrote in kotlin, I fail to find an appropriate syntax which the compiler doen't complain... I'll append my code in kotlin for this in my question later.Moonstone
Oh I just found a way to write in in Kotlin! thanks a lot!Moonstone
I've already added it in my original question. Maybe I should also post it as a new answer.Moonstone
L
1

First initialize spinner at onCreate function.

 var spinner : Spinner ?= null

spinner = findViewById(R.id.spinner) as Spinner 

Now add details with Spinner. Here i have used array from string resource.

 fun addSpinnerData(){

   var arr = (resources.getStringArray(R.array.data_list).toMutableList());
    adapter = ArrayAdapter<String>(
            this,
            android.R.layout.simple_list_item_1,
            arr)

    spinner!!.setAdapter(adapter);

    spinner!!.onItemSelectedListener = object : AdapterView.OnItemSelectedListener{
        override fun onItemSelected(p0: AdapterView<*>?, p1: View?, p2: Int, p3: Long) {
            Toast.makeText(applicationContext," On Click",Toast.LENGTH_SHORT).show();
        }

        override fun onNothingSelected(p0: AdapterView<*>?) {
        }
    }

}

By this way you can achieve onItemSelectedListener for Spinner

Light answered 5/10, 2017 at 10:8 Comment(0)
L
0

You can create a very simple extension function:

file: Extensions.kt

fun Spinner.setOnItemSelectedListener(listener: AdapterView.OnItemSelectedListener) {
    onItemSelectedListener = listener
}

Then you can call it the way you want

spinner.setOnItemSelectedListener(object: AdapterView.OnItemSelectedListener {
    override fun onItemSelected(parent: AdapterView<*>?, view: View?, position: Int, id: Long) {

    }

    override fun onNothingSelected(parent: AdapterView<*>?) {

    }
})

Similar to previous answers, but it looks more like the original version instead of the assignment

Legitimate answered 23/8, 2017 at 5:49 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.