2015-12-31 16 views
74

Wie man Kotlin Android Extensions mit Fragment s verwenden? Wenn ich sie innerhalb onCreateView() verwenden, erhalte ich diese NullPointerException Ausnahme:Kotlin Android Erweiterungen und Fragmente

Verursacht durch: java.lang.NullPointerException: Versuch virtuellen Methode ‚android.view.View android.view.View.findViewById (int aufrufen)‘auf einer null Objektreferenz

ist der Fragment-Code:

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

Wenn Sie es in onCreateView tun möchten, wird btn_K auch eine Eigenschaft auf rootView sein. Sie könnten tun "rootView.btn_K.setOnClickListener" – Makotosan

Antwort

166

Kotlin synthetische Eigenschaften keine Magie sind und WO rk auf sehr einfache Weise. Wenn Sie auf btn_K zugreifen, ruft es getView().findViewById(R.id.btn_K) auf.

Das Problem ist, dass Sie zu früh darauf zugreifen. getView() gibt null in onCreateView zurück. Versuchen Sie es in der onViewCreated Methode tun:

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

Es hat funktioniert !! Vielen Dank. Nur ein kurzer Überblick für zukünftige Referenz. Ich hatte eine weitere Ausnahme und ich grub ein wenig tiefer und es stellte sich heraus, dass die Nullreferenzausnahme von einem asynchronen Callback zum UI-Thread kam, wo sie versuchen würde, auf die synthetische Eigenschaft zuzugreifen, aber sie war zu diesem Zeitpunkt bereits null. Stellen Sie sicher, dass Sie den Operator _Safe Call_ (?.) Oder einen anderen Nullsicherheitsoperator verwenden. Es würde auch helfen, eine Klassenreferenz der Ansicht zu behalten und nicht auf synthetische Eigenschaften außerhalb von 'onViewCreated()' – Solidak

+2

Eine Frage zwar - es erzeugt anderen Code für Aktivität und Fragment? Wenn wir eine andere Struktur verwenden, die 'getView()' nicht enthält oder 'findViewById()' nicht aufrufen kann, gibt es eine Möglichkeit, das Problem zu umgehen? Zum Beispiel, lehren Sie welche Funktion wird mein Layout zurückgeben? – milosmns

+4

Sie können auch wie 'rootView.btn_K' darauf zugreifen, wenn Sie eine Ansicht haben (und nicht nur in Fragmenten, dies kann überall gemacht werden) –

1

Du diesen btn_K Aufruf zu früh, wie es zu dieser Zeit eine null zurück und gibt Ihnen Null-Zeiger-Ausnahme.

Sie können diese Ansichten von diesem synthetischen Plugin in onActivityCreated() Methode, die kurz nach onCreateView() von Fragment Lebenszyklus aufgerufen wird, verwenden.

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

Eine Antwort wurde bereits akzeptiert. – Solidak