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.
**