NullPointerException al intentar acceder a vistas en un fragmento de Kotlin


¿Cómo usar las extensiones de Kotlin para Android con Fragment s? Si los uso dentro de onCreateView(), obtengo esta NullPointerException excepción:

Causado por: java.lang.NullPointerException: Intentar invocar virtual método ' android.vista.Ver android.vista.Vista.findViewById (int) ' on a referencia de objeto null

Aquí está el código del fragmento:

package com.obaied.testrun.Fragment

import android.os.Bundle
import android.support.v4.app.Fragment
import android.util.Log
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import com.obaied.acaan.R
import kotlinx.android.synthetic.main.fragment_card_selector.*

public class CardSelectorFragment : Fragment() {
    val TAG = javaClass.canonicalName

    companion object {
        fun newInstance(): CardSelectorFragment {
            return CardSelectorFragment()
        }
    }

    override fun onCreateView(inflater: LayoutInflater?, container: ViewGroup?, savedInstanceState: Bundle?): View? {
        var rootView = inflater?.inflate(R.layout.fragment_card_selector, container, false)
        btn_K.setOnClickListener { Log.d(TAG, "onViewCreated(): hello world"); }

        return rootView
    }
}
`
Author: Otziii, 2015-12-31

7 answers

Las propiedades sintéticas de Kotlin no son mágicas y funcionan de una manera muy simple. Cuando accede a btn_K, llama a getView().findViewById(R.id.btn_K).

El problema es que está accediendo demasiado pronto. getView() devuelve {[4] {} en[5]}. Intenta hacerlo en el método onViewCreated:

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
    btn_K.setOnClickListener { Log.d(TAG, "onViewCreated(): hello world"); }
}
 249
Author: Egor Neliuba,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-07-07 16:41:49

Está llamando a este btn_K demasiado pronto, ya que en ese momento devuelve un null y le está dando una Excepción de puntero nulo.

Puede usar estas vistas mediante este complemento sintético en el método onActivityCreated() que se llama justo después de onCreateView() del ciclo de vida del fragmento.

onActivityCreated()
{
        super.onActivityCreated(savedInstanceState)
        btn_K.setOnClickListener{}
}
 5
Author: Kashish luthra,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-11-20 12:54:33

En fragmentos por favor escriba su código en onActivityCreated: -

override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
        super.onCreateView(inflater, container, savedInstanceState)
        return inflater.inflate(R.layout.login_activity, container, false)

    }

    override fun onActivityCreated(savedInstanceState: Bundle?) {
        super.onActivityCreated(savedInstanceState)
        callbackManager = CallbackManager.Factory.create()
        initialization()
        onClickLogin()
        onClickForgot()
        onClickSocailLogIn()

  }
 1
Author: abhilasha Yadav,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-05-23 07:17:13

Lo único que tienes que hacer es:

override fun onCreateView(inflater: LayoutInflater?, container: ViewGroup?, savedInstanceState: Bundle?): View? {
    var rootView = inflater?.inflate(R.layout.fragment_card_selector, container, false)
    rootView.btn_K.setOnClickListener { Log.d(TAG, "onViewCreated(): hello world"); }

    return rootView
}
 1
Author: Rhusfer,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-07-16 05:19:35

Propiedades sintéticas generadas por El complemento Kotlin Android Extensions necesita un view para Fragment/Activity que se establezca de antemano.

En su caso, para Fragment, debe usar view.btn_K en onViewCreated

override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
    super.onCreateView(inflater, container, savedInstanceState)
    val view = inflater.inflate(R.layout.fragment_card_selector, container, false)
    view.btn_K.setOnClickListener{} // access with `view`
    return view
}

O mejor, solo debe acceder a propiedades sintéticas en onViewCreated

override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
    super.onCreateView(inflater, container, savedInstanceState)
    return inflater.inflate(R.layout.fragment_card_selector, container, false)
}

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
    super.onViewCreated(view, savedInstanceState)
    btn_K.setOnClickListener{} // access without `view`
}

Tenga en cuenta que el parámetro savedInstanceState debe ser nullable Bundle?, y también verifique Importando propiedades sintéticas

Es conveniente importar todas las propiedades del widget para un diseño específico de una sola vez:

import kotlinx.android.synthetic.main.<layout>.*

Por lo tanto, si el nombre del archivo de diseño es activity_main.xml, importaríamos kotlinx.android.synthetic.main.activity_main.*.

Si queremos llamar a las propiedades sintéticas a la vista, también debemos importar kotlinx.android.synthetic.main.activity_main.view.*.

 1
Author: onmyway133,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-08-06 11:12:32

Si ha escrito código aparentemente correcto, pero aún así obtiene el error; Limpiar, reconstruir y reiniciar Android Studio funcionó para mí..

 0
Author: Otziii,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-09-18 06:46:14
class CardSelectorFragment : Fragment() {


val TAG = javaClass.canonicalName

companion object {
    fun newInstance(): CardSelectorFragment {
        return CardSelectorFragment()
    }
}

override fun onCreateView(inflater: LayoutInflater?, container: ViewGroup?, savedInstanceState: Bundle?): View? {
    var rootView = inflater?.inflate(R.layout.fragment_card_selector, container, false)

    rootView?.findViewById<TextView>(R.id.mTextView)?.setOnClickListener{
        Log.d(TAG, "onViewCreated(): hello world");
    }
    //btn_K.setOnClickListener { Log.d(TAG, "onViewCreated(): hello world"); }
    return rootView
}

}

* * Aquí está usando btn_K. setOnClickListener antes de encontrar - Usted tiene que encontrar el elemento de forma xml a su código java / kotlin mediante el uso de findViewById entonces y solo entonces se puede realizar la operación en esa vista o elemento.

- Así que es por eso que se obtiene la exección puntero nulo

**

 -1
Author: Amit Walke,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-04-10 12:01:29