Исключение NullPointerException для RecyclerView

#android #kotlin #nullpointerexception

#Android #kotlin #исключение nullpointerexception

Вопрос:

Недавно я начал изучать и практиковать разработку для Android с помощью Kotlin, для этого я использовал книгу из Humble bundle около года назад, однако до недавнего времени я мог начать с нее, после каждой главы есть определенные приложения для работы, для просмотра Recycler естьпример с приложением для заметок, после кодирования всех классов, методов и функций, необходимых мне, я столкнулся с этой ошибкой, и после проверки нескольких источников я все еще не могу решить эту проблему, вот строка кода для основного файла

 package com.gree.notas

import android.os.Bundle
import com.google.android.material.floatingactionbutton.FloatingActionButton
import androidx.appcompat.app.AppCompatActivity
import android.view.Menu
import android.view.MenuItem
import android.view.View
import androidx.recyclerview.widget.DefaultItemAnimator
import androidx.recyclerview.widget.DividerItemDecoration
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView

class MainActivity : AppCompatActivity() {
//private var notaTemporal = Notas()
private val listaNotas = ArrayList<Notas>()
private var recyclerView1: RecyclerView? = null
private var adapter: AdaptadorNotas? = null

fun crearNuevaNota(n: Notas){
    //notaTemporal = n
    listaNotas.add(n)
    adapter!!.notifyDataSetChanged()
}

fun mostrarNota(notaMostrar: Int){
    val dialogo = MostrarNota()
    dialogo.enviarNotaSeleccionada(listaNotas[notaMostrar])
    dialogo.show(supportFragmentManager, "")
}

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_main)
    setSupportActionBar(findViewById(R.id.toolbar))

    findViewById<FloatingActionButton>(R.id.fab).setOnClickListener { view ->
        val dialogo = NuevaNota()
        dialogo.show(supportFragmentManager,"")
    }

    recyclerView1 = findViewById<View>(R.id.recyclerView) as RecyclerView
    adapter = AdaptadorNotas(this, listaNotas)
    val layoutManager = LinearLayoutManager(applicationContext)
    recyclerView1!!.layoutManager = layoutManager
    recyclerView1!!.itemAnimator = DefaultItemAnimator()
    recyclerView1!!.addItemDecoration(DividerItemDecoration(this, LinearLayoutManager.VERTICAL))
    recyclerView1!!.adapter = adapter
}

override fun onCreateOptionsMenu(menu: Menu): Boolean {
    menuInflater.inflate(R.menu.menu_main, menu)
    return true
}

override fun onOptionsItemSelected(item: MenuItem): Boolean {
    return when (item.itemId) {
        R.id.action_settings -> true
        else -> super.onOptionsItemSelected(item)
    }
  }
}
 

И вот код для класса адаптера

 package com.gree.notas

import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.TextView
import androidx.recyclerview.widget.RecyclerView

class AdaptadorNotas(private val mainActivity: MainActivity, private val listaNotas: List<Notas>) : RecyclerView.Adapter<AdaptadorNotas.ListItemHolder>() {
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ListItemHolder {
    val itemView = LayoutInflater.from(parent.context).inflate(R.layout.lista, parent, false)

    return ListItemHolder(itemView)
}

override fun getItemCount(): Int {
    if(listaNotas != null){
        return listaNotas.size
    }
    return -1
}

override fun onBindViewHolder(holder: ListItemHolder, position: Int) {
    val nota = listaNotas!![position]
    holder.titulo.text = nota.titulo

    holder.descripcion.text = nota.descripcion!!.substring(0, 15)
    when{
        nota.idea -> holder.estado.text = mainActivity.resources.getString(R.string.texto_idea)
        nota.importante -> holder.estado.text = mainActivity.resources.getString(R.string.texto_importante)
        nota.porHacer -> holder.estado.text = mainActivity.resources.getString(R.string.porhacer_texto)
    }
}

inner class ListItemHolder(view: View) :
    RecyclerView.ViewHolder(view), View.OnClickListener{
        internal var titulo = view.findViewById<View>(R.id.textViewTitle) as TextView
        internal var descripcion = view.findViewById<View>(R.id.textViewDescription) as TextView
        internal var estado =  view.findViewById<View>(R.id.textViewStatus) as TextView
        init {
            view.isClickable = true
            view.setOnClickListener(this)
        }

        override fun onClick(v: View?) {
            mainActivity.mostrarNota(adapterPosition)
        }
    }
 }
 

Если кто-нибудь может помочь мне найти корень проблемы или показать мне, что я должен искать для отладки и поиска нужной информации для этого исключения NullPointerException в журнале сборки, это будет действительно полезно

Комментарии:

1. Отладка в строке 42 приведение равно нулю, где вы добавили неправильную проверку как это!!

2. Вы устанавливаете для вашего RecyclerView значение null при его инициализации в строке 17 вашего кода в MainAcitivity. Как указано в ошибке, вы не можете преобразовать null в ненулевой тип. Возможно, использование lateinit перед var может решить эту проблему.

3. Кроме того, поскольку вам не нужен RecyclerView вне onCreate в MainActivity, вы можете просто вызвать его как есть. частная переменная recyclerView1: RecyclerView? = findViewById<Просмотр>(R.id.RecyclerView)

Ответ №1:

Трассировка стека указывает на эту строку:

 recyclerView1 = findViewById<View>(R.id.recyclerView) as RecyclerView
 

Ошибка (« null невозможно привести к ненулевому типу») означает, что findViewById() возвращается null , поэтому приведение ( as RecyclerView ) завершается с ошибкой.

Это означает, что @ id/recyclerView в вашем макете нет представления с идентификатором. Вы вызвали setContentView(R.layout.activity_main) , поэтому убедитесь, что представление с этим идентификатором существует activity_main.xml .

Комментарии:

1. Спасибо за комментарий, я думаю, что это может быть проблемой, поскольку @ id / RecyclerView отсутствует конкретно в этом макете, он включен в другой макет с именем firstfragment.xml и включен в content_main, а затем с фрагментом, показанным на activity_main.xml с помощью этой строки кода <include layout="@layout/content_main" />