ViewHolder with onClicklistener Issue with UninitializedPropertyAccessException

I’m a beginner so please bare with me.

I have a viewholder that has an onclicklistener.

The aim of the click is to send a Url string into another fragment using Jetpack Navigation (hopefully i did it right)

the Url is being created within the dataclass itself.

but i keep getting this error:

kotlin.UninitializedPropertyAccessException: lateinit property galleryItem has not been initialized

I tried working around using companion object and other ways, nothing worked… is there a solution for this?

here is the view holder and data class

import android.annotation.SuppressLint
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.ImageButton
import androidx.core.os.bundleOf
import androidx.navigation.Navigation
import androidx.paging.PagingDataAdapter
import androidx.recyclerview.widget.DiffUtil
import androidx.recyclerview.widget.RecyclerView
import com.bumptech.glide.Glide
import com.saheralsous.android.R
import com.saheralsous.android.database.remote.model.PagingData

class RecyclerViewPhotoAdapter() :
    PagingDataAdapter<PagingData.GalleryItem, PhotoHolder>(
        diffCallback = DiffCallback
    ) {
    override fun onBindViewHolder(holder: PhotoHolder, position: Int) {
        getItem(position)?.let {
            holder.bind(it)
        }
    }

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): PhotoHolder {
        val view = LayoutInflater.from(parent.context).inflate(R.layout.photo_item_view,parent,false)
        return PhotoHolder(view)
    }
}

class PhotoHolder(view: View):
    RecyclerView.ViewHolder(view), View.OnClickListener {
    
    private val imageButtom: ImageButton = view.findViewById(R.id.ImageButton)
    private lateinit var galleryItem: PagingData.GalleryItem //page. 594


    @SuppressLint("ResourceType")
    fun bind(galleryItem : PagingData.GalleryItem){
        /*
        idTextView.text = galleryItem.id
        ownerTextView.text = galleryItem.owner
        titleTextView.text = galleryItem.title
        urlTextView.text = galleryItem.url
         */
        galleryItem.url.let { url ->
            Glide.with(itemView)
                .load(url)
                .override(350,350)
                .into(imageButtom)
        }
    }

    init {
        imageButtom.setOnClickListener(this)
    }

    override fun onClick(v: View?) {
        println("item was clicked")
        val bundle = bundleOf("url" to galleryItem.photoPageUri )  <-- here is the issue
        Navigation.findNavController(v!!).navigate(
            R.id.action_photoGalleryFragment_to_photoPageFragment,
            bundle)
    }
}




object DiffCallback : DiffUtil.ItemCallback<PagingData.GalleryItem>() {

    override fun areItemsTheSame(oldItem: PagingData.GalleryItem, newItem: PagingData.GalleryItem): Boolean {
        // Id is unique.
        return oldItem.id == newItem.id
    }

    override fun areContentsTheSame(oldItem: PagingData.GalleryItem, newItem: PagingData.GalleryItem): Boolean {
        return oldItem == newItem
    }
}

data class

import android.net.Uri
import androidx.annotation.Keep
import com.google.gson.annotations.SerializedName

data class PagingData(
    val total : Int =0,
    val Page: Int = 0,
    val photos : List<GalleryItem>
){
    val endOfPage = total == Page

    @Keep
    data class GalleryItem(
        @SerializedName("id")
        val id: String,
        @SerializedName("owner")
        val owner: String,
        @SerializedName("title")
        var title: String,
        @SerializedName("url_s")
        val url: String) {
        val photoPageUri : Uri <-- here is the value
            get() {
                return Uri.parse("https://www.flickr.com/photos/")
                    .buildUpon()
                    .appendPath(owner)
                    .appendPath(id)
                    .build()
            }
    }
}

Answer

As the error states, you haven’t initialised the galleryItem instance variable in your PhotoHolder. Add this inside your bind method:

this.galleryItem = galleryItem