Kotlin Android Extensions et Fragments

Comment utiliser les extensions Kotlin Android avec Fragment s? Si je les utilise dans onCreateView() , j’obtiens cette exception NullPointerException :

Causée par: java.lang.NullPointerException: tentative d’invocation de la méthode virtuelle ‘android.view.View android.view.View.findViewById (int)’ sur une référence d’object NULL

Voici le code du fragment:

 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 } } ` 

Les propriétés synthétiques Kotlin ne sont pas magiques et fonctionnent de manière très simple. Lorsque vous accédez à btn_K , il appelle getView().findViewById(R.id.btn_K) .

Le problème est que vous y accédez trop tôt. getView() renvoie null dans onCreateView . Essayez de le faire dans la méthode onViewCreated :

 override fun onViewCreated(view: View, savedInstanceState: Bundle?) { btn_K.setOnClickListener { Log.d(TAG, "onViewCreated(): hello world"); } } 

Vous appelez cette btn_K trop tôt car à ce moment-là, elle retourne un null et vous donne une exception de pointeur nul.

Vous pouvez utiliser ces vues avec ce plug-in synthétique dans la méthode onActivityCreated() appelée juste après onCreateView() du cycle de vie Fragment.

 onActivityCreated() { super.onActivityCreated(savedInstanceState) btn_K.setOnClickListener{} } 

Dans Fragments, écrivez votre code sur 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() } 

La seule chose à faire est:

 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 } 

Les propriétés synthétiques générées par le plug-in Kotlin Android Extensions nécessitent une view pour Fragment/Activity à définir avant la main.

Dans votre cas, pour Fragment , vous devez utiliser view.btn_K dans 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 } 

Ou mieux, vous devez uniquement accéder aux propriétés synthétiques dans 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` } 

Veuillez noter que le paramètre savedInstanceState doit être Nullable Bundle? , et cochez également Importer des propriétés synthétiques

Il est pratique d’importer toutes les propriétés du widget pour une mise en page spécifique en une seule fois:

import kotlinx.android.synthetic.main..*

Ainsi, si le nom de fichier de la mise en page est activity_main.xml, nous importons kotlinx.android.synthetic.main.activity_main.*.

Si nous voulons appeler les propriétés synthétiques sur View, nous devons également importer kotlinx.android.synthetic.main.activity_main.view.*.

 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(R.id.mTextView)?.setOnClickListener{ Log.d(TAG, "onViewCreated(): hello world"); } //btn_K.setOnClickListener { Log.d(TAG, "onViewCreated(): hello world"); } return rootView } 

}

** Ici, vous utilisez btn_K.setOnClickListener avant de trouver -Vous devez trouver l’élément au format XML à votre code java / kotlin en utilisant findViewById alors et seulement vous pouvez effectuer une opération sur cette vue ou cet élément.

-Alors c’est pourquoi l’exécution de pointeur null vous avez

**