Исключение NullPointerException при попытке доступа к представлениям во фрагменте Kotlin
как использовать расширения Kotlin Android с Fragment
s?
Если я использую их внутри onCreateView()
, Я понял это NullPointerException
исключения:
вызвано: java.ленг.NullPointerException: попытка вызвать виртуальный метод 'для Андроид.вид.Вид на Андроид.вид.Вид.findViewById (int)' на a нулевая ссылка на объект
вот фрагмент кода:
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
}
}
`
7 ответов:
синтетические свойства Котлина не волшебны и работают очень простым способом. Когда вы получаете доступ
btn_K
, он требуетgetView().findViewById(R.id.btn_K)
.проблема в том, что вы получаете доступ к нему слишком рано.
getView()
возвращаетnull
наonCreateView
. Попробуйте сделать это вonViewCreated
способ:override fun onViewCreated(view: View, savedInstanceState: Bundle?) { btn_K.setOnClickListener { Log.d(TAG, "onViewCreated(): hello world"); } }
вы называете это
btn_K
слишком рано, как в то время он возвращает null и дает вам исключение нулевого указателя.вы можете использовать эти представления с помощью этого синтетического плагина в
onActivityCreated()
метод, который вызывается сразу послеonCreateView()
жизненный цикл фрагмента.onActivityCreated() { super.onActivityCreated(savedInstanceState) btn_K.setOnClickListener{} }
во фрагментах, пожалуйста, напишите свой код в 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() }
единственное, что вам нужно сделать, это:
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 }
синтетические свойства, созданные Kotlin Android Extensions plugin нужен
view
наFragment/Activity
должен быть установлен, прежде чем руки.в вашем случае, для
Fragment
, вы должны использоватьview.btn_K
на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 }
или лучше, вы должны получить доступ только к синтетическим свойствам в
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` }
Пожалуйста, обратите внимание, что
savedInstanceState
параметр должен быть nullableBundle?
, а также чек импорт синтетических свойстваудобно импортировать все свойства виджета для конкретного макета одним махом:
import kotlinx.android.synthetic.main.<layout>.*
таким образом, если имя файла макета activity_main.xml, мы бы импортировали
kotlinx.android.synthetic.main.activity_main.*.
если мы хотим вызвать синтетические свойства на вид, мы должны также импорт
kotlinx.android.synthetic.main.activity_main.view.*.
Если вы написали, казалось бы, правильный код, но все равно получите ошибку; Чистый, перестроить и перезапустить Android Studio работал для меня..
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<TextView>(R.id.mTextView)?.setOnClickListener{ Log.d(TAG, "onViewCreated(): hello world"); } //btn_K.setOnClickListener { Log.d(TAG, "onViewCreated(): hello world"); } return rootView }
}
* * здесь вы используете btn_K. setOnClickListener перед поиском -Вы должны найти xml-форму элемента для вашего кода java/kotlin с помощью findViewById, а затем только вы можете выполнить операцию над этим представлением или элементом.
- так вот почему нулевой указатель execption вы получили
**