Свойство lateinit onItemClickCallback не было инициализировано - PullRequest
0 голосов
/ 19 октября 2019

Я новичок на Android и Kotlin. Я делаю onclick слушатель для моего cardViewAdapter, используя интерфейс, чтобы я мог переопределить его обратный вызов из моей деятельности. Но я получаю ошибку «свойство lateinit onItemClick не было инициализировано» при запуске его на эмуляторе и щелкает каждый элемент ViewView.

В своем коде я попытался инициализировать его внутри функции. До этого я пробовал этот ответ от другого, поэтому https://stackoverflow.com/a/46076355/7587265, но onclick не работает

, это мой MainActivity.kt

rvMotor.layoutManager = GridLayoutManager(this, 2)
val recycleViewAdapter = CardViewMainAdapter(listMotor)
recycleViewAdapter.setOnItemClickCallback(object : CardViewMainAdapter.OnItemClickCallback{
    override fun onItemClicked(data: Motor) {
        val intent = Intent(this@MainActivity, DetailActivity::class.java)
        intent.putExtra(DetailActivity.EXTRA_ID, data.id)
        startActivity(intent)
    }
})

rvMotor.adapter = recycleViewAdapter

, и это мой CardViewMainAdapter.kt

class CardViewMainAdapter(private val listMotors: ArrayList<Motor>) :
    RecyclerView.Adapter<CardViewMainAdapter.CardViewMainViewHolder>() {

    private lateinit var onItemClickCallback : OnItemClickCallback

    fun setOnItemClickCallback(onItemClickCallback: OnItemClickCallback){
        this.onItemClickCallback = onItemClickCallback
    }

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

    override fun getItemCount(): Int {
        return listMotors.size
    }

    override fun onBindViewHolder(holder: CardViewMainViewHolder, position: Int) {
        val motor = listMotors[position]

        holder.cvMainName.text = motor.name
        Glide.with(holder.itemView.context)
            .load(motor.image)
            .apply(RequestOptions().override(350, 550))
            .into(holder.cvMainImage)

        holder.itemView.setOnClickListener{
            onItemClickCallback.onItemClicked(listMotors[holder.adapterPosition])
        }
    }

    inner class CardViewMainViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView){
        var cvMainImage: ImageView = itemView.findViewById(R.id.cardview_main_img)
        var cvMainName: TextView = itemView.findViewById(R.id.cardview_main_txt)
    }

    interface OnItemClickCallback {
        fun onItemClicked(data: Motor)
    }
}

Ответы [ 3 ]

0 голосов
/ 19 октября 2019

Согласно официальному документу , перед использованием свойства lateinit можно проверить, инициализировано ли оно или нет, используя isInitialized, как показано ниже:

::onItemClickCallback.isInitialized

lateinit свойствоудобен во время DI (Dependency Injection) и UnitTest. В противном случае, в обычных случаях это похоже на свойство типа Non Null, которое должно быть инициализировано в конструкторе

0 голосов
/ 25 октября 2019

Я закончил инициализацией onItemClickCallback внутри параметра адаптера, а не из функции. Я думал, что пытался таким образом, но по неизвестной причине, это не работает раньше. Спасибо за все ответы. это моя деятельность

val recycleViewAdapter = CardViewMainAdapter(listMotor, object : CardViewMainAdapter.OnItemClickCallback{
            override fun onItemClicked(data: Motor) {
                val intent = Intent(this@MainActivity, DetailActivity::class.java)
                intent.putExtra(DetailActivity.EXTRA_ID, data.id)
                startActivity(intent)
            }
        })

rvMotor.adapter = recycleViewAdapter

это мой адаптер

class CardViewMainAdapter(private val listMotors: ArrayList<Motor>, private val onItemClickCallback: OnItemClickCallback) :
    RecyclerView.Adapter<CardViewMainAdapter.CardViewMainViewHolder>() {
0 голосов
/ 19 октября 2019

Согласно документу: При доступе к свойству lateinit до его инициализации выдается специальное исключение, которое четко идентифицирует доступное свойство и тот факт, что оно не было инициализировано.

Чтобы проверить, инициализирована ли переменная lateinit, используйте .isInitialized для ссылки на это свойство:

Я не знаю, почему это вызывает проблему здесь. Я думаю, ваш код в порядке, но я могу дать вам решение вашей проблемы.

В вашем случае вы можете решить вашу проблему двумя способами.

1. Просто добавьте условие if в прослушиватель кликов, чтобы проверить, используется оно или нет.

 holder.itemView.setOnClickListener{

        //Check whether it is Initialized or not
        if(::onItemClickCallback.isInitialized){
            onItemClickCallback.onItemClicked(listMotors[holder.adapterPosition])
        }
    }

ИЛИ

2. удалить латент и сделать его обнуляемым.

    //Make it as nullable
    private  var onItemClickCallback : OnItemClickCallback? = null

    holder.itemView.setOnClickListener {

        holder.itemView.setOnClickListener {
            // add ? for handling nullable 
            onItemClickCallback?.onItemClicked(listMotors[holder.adapterPosition])
        }

    }
...