2015-12-31 15 views
74

Come utilizzare le estensioni Android Kotlin con Fragment s? Se li uso all'interno onCreateView(), ottengo questo NullPointerException eccezione:Estensioni e frammenti di Kotlin Android

Causato da: java.lang.NullPointerException: Tentativo di richiamare metodo 'virtuale android.view.View android.view.View.findViewById (int)' su un nullo oggetto di riferimento

Ecco il frammento di codice:

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

Se si desidera farlo in onCreateView, btn_K sarà anche una proprietà su rootView. Si potrebbe fare 'rootView.btn_K.setOnClickListener' – Makotosan

risposta

166

Kotlin proprietà sintetici non sono magici e WO rk in un modo molto semplice. Quando si accede a btn_K, si richiede getView().findViewById(R.id.btn_K).

Il problema è che si sta accedendo troppo presto. getView() restituisce null in onCreateView. Provare a farlo nel metodo onViewCreated:

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

Ha funzionato !! Grazie. Solo un rapido heads-up per riferimento futuro. Avevo un'altra eccezione, e ho scavato un po 'più a fondo e si scopre che l'eccezione Null Reference proveniva da un callback asincrono al thread dell'interfaccia utente in cui tentava di accedere alla proprietà sintetica, ma era già nullo al momento. Assicurarsi di utilizzare l'operatore _Safe Call_ (?.) O un altro operatore di sicurezza null. Sarebbe anche utile mantenere un riferimento di classe della vista e non fare affidamento su proprietà sintetiche al di fuori di 'onViewCreated()' – Solidak

+2

Una domanda però - genera codice diverso per Attività e Frammento? Se usiamo un'altra struttura che non contiene 'getView()' o non può richiamare 'findViewById()', c'è un modo per aggirarla? Ad esempio, insegnagli quale funzione restituirà il mio layout? – milosmns

+4

Puoi anche accedervi come 'rootView.btn_K' se hai una vista (e non solo in frammenti, questo può essere fatto ovunque) –

1

Si chiama questo btn_K troppo presto come in quel momento non restituisce alcun risultato e si sta dando Null Pointer Exception.

È possibile utilizzare queste visualizzazioni con questo plug-in sintetico nel metodo onActivityCreated() che viene chiamato subito dopo onCreateView() del ciclo di vita di Fragment.

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

Una risposta era già stata accettata. – Solidak