I have an activity with a menu from which a custom dialog is displayed that I have created in the layout folder.
I get the error when I want to display the dialog from the method onOptionsItemSelected
that I am calling from the activity PlayerVideosActivity
java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.Button.setOnClickListener(android.view.View$OnClickListener)' on a null object reference
override fun onCreateOptionsMenu(menu : Menu): Boolean{
menuInflater.inflate(R.menu.menu_visitas, menu)
return true
}
override fun onOptionsItemSelected(item : MenuItem): Boolean {
val dialog = AlertDialog.Builder(this@ReproductorVideosActivity)
val dialogView = layoutInflater.inflate(R.layout.dialog_visitas, null)
val tvTitulo = findViewById<TextView>(R.id.dialog_tvTitulo)
val tvVisitas = findViewById<TextView>(R.id.dialog_tvVisitas)
val etVisitasMin = findViewById<EditText>(R.id.dialog_etVisitasMin)
val etVisitasMax = findViewById<EditText>(R.id.dialog_etVisitasMax)
val btnGuardar = findViewById<Button>(R.id.dialog_btnGuardar)
val btnCancelar = findViewById<Button>(R.id.dialog_btnCancelar)
dialog.setView(dialogView)
val dialog1 = dialog.create()
dialog1.show()
//Botón cancelar de dialog
btnCancelar.setOnClickListener(View.OnClickListener() {
fun onClick(v: View) {
dialog1.dismiss()
}
})
return true
}
I have seen possible solutions, but the problem is that I have created the dialog before, I don't create it at the moment from the AlertDialog.Builder
https://stackoverflow.com/questions/12600877/setonclicklistener-error-in-custom-dialog
And I've tried that way, which makes the dialog appear without error, but the buttons don't do anything.
EDIT:
With what they have answered me, it no longer fails, when clicking on the button in the menu it launches the dialog but when pressing the button it does nothing. The code right now is like this
override fun onCreateOptionsMenu(menu : Menu): Boolean{
menuInflater.inflate(R.menu.menu_visitas, menu)
return true
}
override fun onOptionsItemSelected(item : MenuItem): Boolean {
val dialog = AlertDialog.Builder(this@ReproductorVideosActivity)
val dialogView = layoutInflater.inflate(R.layout.dialog_visitas, null)
val tvTitulo = dialogView.findViewById<TextView>(R.id.dialog_tvTitulo)
val tvVisitas = dialogView.findViewById<TextView>(R.id.dialog_tvVisitas)
val etVisitasMin = dialogView.findViewById<EditText>(R.id.dialog_etVisitasMin)
val etVisitasMax = dialogView.findViewById<EditText>(R.id.dialog_etVisitasMax)
val btnGuardar = dialogView.findViewById<Button>(R.id.dialog_btnGuardar)
val btnCancelar = dialogView.findViewById<Button>(R.id.dialog_btnCancelar)
dialog.setView(dialogView)
val dialog1 = dialog.create()
dialog1.show()
//Botón cancelar de dialog
btnCancelar.setOnClickListener(View.OnClickListener() {
fun onClick(v: View) {
dialog1.dismiss()
}
})
return true
}
findViewById
it searches in the layout of the activty therefore it will never find the view with the idR.id.dialog_btnCancelar
because it is not in the activity but in the dialog. All you have to do to find it is look for it within the dialog's viewEDIT Solution to the second problem
The syntax you used to define the clickListener is from Java. In Kotlin you don't need to declare the method because everything inside the curly braces
{}
is already the implementation of that method. I mean you just had to write thisWhat your original code did was create a local function but it never executed it. For it to work that way you would have to have called that function after declaring it
Although of course this generates unnecessary overhead.
In these cases, the ideal is to use the trailing lambda syntax