2015-12-31 12 views
74

Jak korzystać z rozszerzeń dla kotlin Android z Fragment s? Gdybym ich używać wewnątrz onCreateView(), otrzymuję ten NullPointerException wyjątek:Rozszerzenia i fragmenty z Androidem Kotlin

spowodowane: java.lang.NullPointerException: Próba wywołania wirtualnego metodę „android.view.View android.view.View.findViewById (int)”na zerowego odniesienia do obiektu

Oto fragment kodu:

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

Jeśli chcesz to zrobić w onCreateView, btn_K będzie również własnością rootView. Możesz zrobić "rootView.btn_K.setOnClickListener' – Makotosan

Odpowiedz

166

Kotlin właściwości syntetyczne nie są magiczne wo rk w bardzo prosty sposób. Po uzyskaniu dostępu do btn_K, wywołuje on getView().findViewById(R.id.btn_K).

Problem polega na tym, że uzyskujesz do niego dostęp zbyt wcześnie. getView() zwraca null w onCreateView. Spróbuj zrobić to w sposób onViewCreated:

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

Udało się! Dzięki. Wystarczy szybki heads-up na przyszłość. Miałem inny wyjątek, a ja wykopałem się nieco głębiej i okazało się, że wyjątek odwołania Null pochodzi z asynchronicznego wywołania zwrotnego do wątku interfejsu użytkownika, w którym próbowałby uzyskać dostęp do właściwości syntetycznej, ale w tym czasie był już pusty. Upewnij się, że korzystasz z operatora Bezpieczne połączenie (?.) Lub jakiegoś innego operatora bezpieczeństwa o wartości zerowej. Pomoże to również zachować odniesienie do klasy widoku i nie będzie polegać na własnościach syntetycznych poza 'onViewCreated()' – Solidak

+2

Jedno pytanie jednak - generuje inny kod dla działania i fragmentu? Jeśli użyjemy innej struktury, która nie zawiera 'getView()' lub nie może wywołać 'findViewById()', czy istnieje sposób obejścia tego? Na przykład, naucz, która funkcja zwróci mój układ? – milosmns

+4

Możesz także uzyskać do niego dostęp w postaci 'rootView.btn_K', jeśli masz widok (a nie tylko fragmenty, można to zrobić wszędzie) –

1

Telefonujesz ten btn_K zbyt szybko, jak w tym czasie zwraca wartość null i daje ci Null Pointer wyjątku.

Możesz użyć tych widoków za pomocą tej syntetycznej wtyczki w metodzie onActivityCreated(), która jest wywoływana tuż po onCreateView() cyklu życia Fragmentu.

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

Odpowiedź została już zaakceptowana. – Solidak