1

I have created a custom spinner adapter which returns two views (item_new_area & item_area), item_new_area is static with an option Add New and item_area populated dynamic.

enter image description here

When Add new is selected,I want to launch the dialog for add new area but i keep on getting an error that lateinit property listener has not been initialized

Custom Spinner Adapter

class AreaSpinnerAdapter(private val inflater: LayoutInflater) : BaseAdapter() {
var areas: List<AreaEntity>? = null
lateinit var listener: OnItemSelectedListener

override fun getView(position: Int, convertView: View?, parent: ViewGroup?): View {

    return when (getItemViewType(position)) {
        1 -> {
            val binding: ItemNewAreaBinding = DataBindingUtil.inflate<ItemNewAreaBinding>(
                inflater,
                R.layout.item_new_area,
                parent, false
            ).also {
                it.root.tag = it
            }

            binding.addNew.setOnClickListener {
                listener.onClick()

            }
            binding.root
        }
        else -> {
            val binding: ItemAreaBinding = DataBindingUtil.inflate<ItemAreaBinding>(
                inflater,
                R.layout.item_area,
                parent, false
            ).also {
                it.root.tag = it
            }
            binding.area = getItem(position)
            binding.root
        }
    }
}

override fun getItemViewType(position: Int): Int {
    return if (position == 1) {
        1
    } else {
        2
    }
}

fun setOnItemClickListener(listener: OnItemSelectedListener) {
    this.listener = listener
}


interface OnItemSelectedListener {
    fun onClick()
}

}

I try to set the on Item Clicked listener in the onCreateView method of my fragment:

val spinnerAdapter = AreaSpinnerAdapter(layoutInflater)
    spinnerAdapter.setOnItemClickListener(object :
        AreaSpinnerAdapter.OnItemSelectedListener {
        override fun onClick() {
            addNewAreaDialog()
        }
    })

    binding?.spinnerArea?.adapter = spinnerAdapter

Error Log

 kotlin.UninitializedPropertyAccessException: lateinit property listener has not been initialized
    at com.test.adapter.AreaSpinnerAdapter.getListener(AreaSpinnerAdapter.kt:15)
    at com.test.adapter.AreaSpinnerAdapter$getView$1.onClick(AreaSpinnerAdapter.kt:50)

line 15 = lateinit var listener: OnItemSelectedListener

line 25 = listener.onClick()

I know that am supposed to initialize the listener before i call getView method but for some reasons am failing to initialize the listener, Any help on how to do it shall be be greatly appreciated. Thanks

braop
  • 186
  • 12

1 Answers1

2

You need to move the listener AreaSpinnerAdapter to the constructor.

class AreaSpinnerAdapter(
    private val inflater: LayoutInflater,
    private val listener: OnItemSelectedListener
        ) : BaseAdapter() {
    var areas: List<AreaEntity>? = null

and then call it like

val spinnerAdapter = AreaSpinnerAdapter(layoutInflater, 
object: AreaSpinnerAdapter.OnItemSelectedListener {
    override fun onClick() {
        addNewAreaDialog()
    }
})
Atiq
  • 14,435
  • 6
  • 54
  • 69
  • when i do this i get red line saying interface OnItemSelectedListener doesn't have constructors. – braop Jul 02 '20 at 08:29
  • Thank you @Max, Your solution works like charm: I actually also found out that my code works perfectly fine. I was accidentally setting the adapter to the spinner before initializing the listener above this line [ val spinnerAdapter = AreaSpinnerAdapter(layoutInflater) ] in onCreatView function. After removing it worked perfectly fine. – braop Jul 02 '20 at 14:24
  • Thanks. This works. But my spinner dialog is not closed after item tap. Could you provide some solution for that too please? – pereckeSokSzam Dec 10 '20 at 02:47