Home > Mobile >  How to initialize viewHolder in RecyclerView adapter for Android in Kotlin
How to initialize viewHolder in RecyclerView adapter for Android in Kotlin

Time:12-09

How should I initialize viewHolder? I have this error: What I want to do is to get selected item in recyclerView but without using onClick method. When I get this selected item I need to show Toast message. Item is data class.

Process: com.pors.coopreaderlast, PID: 7862 kotlin.UninitializedPropertyAccessException: lateinit property viewHolder has not been initialized at com.pors.coopreaderlast.features.polozka.PolozkaAdapter.getViewHolder(PolozkaAdapter.kt:18) at com.pors.coopreaderlast.features.polozka.PolozkaAdapter.getCurrentItem(PolozkaAdapter.kt:46) at com.pors.coopreaderlast.features.polozka.PolozkaActivity.onStart(PolozkaActivity.kt:213)

this is for line where viewHolder is set in Adapter: lateinit var viewHolder: PolozkaViewHolder

This is Adapter

class PolozkaAdapter(val chosen_item: Int, private val listener: OnItemClickListener): ListAdapter<Polozka, PolozkaAdapter.PolozkaViewHolder>(DiffCallback()){
    var selectedItemPosition: Int = chosen_item
    lateinit var viewHolder: PolozkaViewHolder

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): PolozkaViewHolder {
        val binding = PolozkyItemBinding.inflate(LayoutInflater.from(parent.context), parent, false)
        viewHolder = PolozkaViewHolder(binding)
        return viewHolder
    }
    override fun onBindViewHolder(holder: PolozkaViewHolder, position: Int) {
        val currentItem = getItem(position)
        holder.bind(currentItem)
        if (selectedItemPosition == position){
            holder.itemView.setBackgroundColor(Color.parseColor("#DA745A"))
        } else{
            holder.itemView.setBackgroundColor(Color.TRANSPARENT)
        }
    }
    fun getCurrentItem(): Polozka = super.getItem(viewHolder.bindingAdapterPosition)    

    inner class PolozkaViewHolder(private val binding: PolozkyItemBinding): RecyclerView.ViewHolder(binding.root){
        init {
            binding.root.setOnClickListener{
                val position = bindingAdapterPosition
                if (position != RecyclerView.NO_POSITION){
                    val item = getItem(position)
                    if (item != null){
                        listener.onItemClick(item, position)                        
                    }
                }
                notifyItemChanged(selectedItemPosition)                
                selectedItemPosition = bindingAdapterPosition
                notifyItemChanged(selectedItemPosition)
            }            
        }

        fun bind(polozkaPolozka: Polozka){
            binding.apply {
                tvKDE.text = polozkaPolozka.znacky
                tvREG.text = polozkaPolozka.reg
                tvVB.text = polozkaPolozka.veb.toString()  
            }
        }
        }
    }
    interface OnItemClickListener{
        fun onItemClick(polozkaDoklad: Polozka, position: Int)        
    }
    class DiffCallback: DiffUtil.ItemCallback<Polozka>(){
        override fun areItemsTheSame(oldItem: Polozka, newItem: Polozka) =
            oldItem.pvp06pk == newItem.pvp06pk
        override fun areContentsTheSame(oldItem: Polozka, newItem: Polozka) =
            oldItem == newItem
    }
}

This is onStart method but it can be in onCreate method also.

 override fun onStart() {
        super.onStart()
        
        val polozkaAdapter = PolozkaAdapter(idPositionItem, this)
        val selectedItem = polozkaAdapter.getCurrentItem()        
    }

CodePudding user response:

You are calling polozkaAdapter.getCurrentItem() in the onStart() method of your activity. At this point no items exist in your adapter so the latenit var viewHolder has not yet been initialised.

CodePudding user response:

onCreateViewHolder should always return a new instance of a ViewHolder, not a single instance.

  • Related