I have a problem with the spinner inside a fragment. The spinner is filled with data, but when I select an item I don't see logs, and in the spinner, it does not select elements. When I used nearly the same code as an activity it worked (Just changed the context to this in the adapter)
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
val view = inflater.inflate(R.layout.fragment_edit_stoper, container, false)
val tagSpinner = view.findViewById<Spinner>(R.id.editSpinner)
val items: MutableList<String> = ArrayList("a","b","c")
tagSpinner.adapter = ArrayAdapter(this.requireActivity(), android.R.layout.simple_spinner_item, items) as SpinnerAdapter
tagSpinner.onItemSelectedListener = this
return view
}
override fun onItemSelected(parent: AdapterView<*>?, view: View?, position: Int, id: Long) {
Log.d(TAG,"OnItemSelected: $type")
}
override fun onNothingSelected(parent: AdapterView<*>?) {
Log.d(TAG,"error")
}
}
Is your fragment really a listener for spinner?
Write a custom listener and use that instead of your fragment.
inner class SpinnerStateChangeListener : AdapterView.OnItemSelectedListener {
override fun onItemSelected(parent: AdapterView<*>?, view: View?, position: Int, id: Long) {
// do sth here
}
override fun onNothingSelected(parent: AdapterView<*>?) {
// do sth here
}
}
Now you can set your listener like this:
tagSpinner.onItemSelectedListener = SpinnerStateChangeListener()
Try moving your implementation from Fragment directly to spinner. remove override from class and instead of
tagSpinner.onItemSelectedListener = this
do
tagSpinner.onItemSelectedListener = object :AdapterView.OnItemSelectedListener{
override fun onNothingSelected(parent: AdapterView<*>?) {
Log.d(TAG,"error")
}
override fun onItemSelected(parent: AdapterView<*>?, view: View?, position: Int, id: Long) {
Log.d(TAG,"OnItemSelected: $type")
}
}
The solution is to add requireActivity().applicationContext in the adapter to change the activityFragment to a context:
...
val items: MutableList<String> = ArrayList("a","b","c")
tagSpinner.adapter = ArrayAdapter(requireActivity().applicationContext, android.R.layout.simple_spinner_item, items) as SpinnerAdapter
tagSpinner.onItemSelectedListener = this
...
Related
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")
}
}
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
Good day
I have a customized spinner and it shows the string array without any issue. But when I add the onItemSelectedListener my application will crash when loading the fragment.
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
auth = Firebase.auth
// show back button
val activity = activity as? MainActivity
activity?.supportActionBar?.setDisplayHomeAsUpEnabled(true)
val result = inflater.inflate(R.layout.fragment_new_key, container, false)
val spinner: Spinner = result.findViewById(R.id.spinner_Category)
ArrayAdapter.createFromResource(
requireContext(), R.array.keyCategory, R.layout.spinner_item
).also { adapter ->
spinner.adapter = adapter
}
// without adding the below, the application will work smoothly
spinner.onItemSelectedListener = object : AdapterView.OnItemSelectedListener {
override fun onNothingSelected(parent: AdapterView<*>?) {
TODO("Not yet implemented")
}
override fun onItemSelected(parent: AdapterView<*>?, view: View?, position: Int, id: Long) {
TODO("Not yet implemented")
}
}
return result
}
Could you please help, is there something conflicting with the spinner that pushed the application to crash?
Thank you.
Remove these lines
TODO("Not yet implemented")
TODO throws NotImplementedError
I created a custom spinner adapter, populated with data, on runtime it drops the list, but nothing can be selected. The selection works with the stock ArrayAdapter, but the custom. Please help, what am I missig...
DetailsActivity.kt:
'''class DetailsActivity : AppCompatActivity() {
.
.
.
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.word_details)
val spinner: Spinner = findViewById(R.id.topic_spinner)
spinner.adapter = cAdapter(applicationContext, fillSpinner())
val listener = object : AdapterView.OnItemSelectedListener{
override fun onItemSelected(parent: AdapterView<*>?, view: View, pos: Int, id: Long) {
Toast.makeText(applicationContext, "Selected: $pos", Toast.LENGTH_SHORT).show()
}
override fun onNothingSelected(parent: AdapterView<*>?) {
}
}
spinner.onItemSelectedListener = listener
.
.
.
'''
fillSpinner function:
'''
fun fillSpinner(): ArrayList{
val topics = ArrayList<String>()
topics.clear()
val h_cursor = dbHandler.get_h_AllRow()
h_cursor.moveToFirst()
while (!h_cursor.isAfterLast){
topics.add(h_cursor.getString(h_cursor.getColumnIndex(DBHelper.H_COLUMN_TOPIC)))
h_cursor.moveToNext()
}
return topics
}
'''
cAdapter class:
'''
class cAdapter(val ctx: Context, val items: ArrayList) :
ArrayAdapter(ctx, 0, items) {
override fun getView(position: Int, recycledView: View?, parent: ViewGroup): View {
return this.createView(position, recycledView, parent)
}
override fun getDropDownView(position: Int, recycledView: View?, parent: ViewGroup): View {
return this.createView(position, recycledView, parent)
}
private fun createView(position: Int, recycledView: View?, parent: ViewGroup): View {
val item = getItem(position)
val view = recycledView ?: LayoutInflater.from(context).inflate(
R.layout.spinner_layout,
parent,
false)
view.IB_cancel.setImageResource(android.R.drawable.ic_delete)
view.IB_cancel.setOnClickListener {
Toast.makeText(context, "DELETE SOMETHING!", Toast.LENGTH_SHORT).show()
}
view.t_sp_holder.text = item
return view
}
}
'''
As I see, the problem should lie somewhere here in theese lines. Please give some advice, I am new at Kotlin.
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")
}