code

Null 포인터Kotlin 조각에서 보기에 액세스하려고 할 때 예외 발생

starcafe 2023. 8. 6. 10:15
반응형

Null 포인터Kotlin 조각에서 보기에 액세스하려고 할 때 예외 발생

Kotlin Android Extensions를 사용하는 방법Fragments? 안에서 사용하면,onCreateView()알겠습니다NullPointerException예외:

원인: java.lang.Null 포인터예외:가상 메서드 'android.view'를 호출하려고 합니다.Android.view를 봅니다.null 개체 참조의 View.findViewById(int)'

다음은 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
    }
}
`

코틀린 합성 특성은 마법이 아니며 매우 간단한 방법으로 작동합니다.액세스할 때btn_K을 요구합니다.getView().findViewById(R.id.btn_K).

문제는 당신이 너무 빨리 접속하고 있다는 것입니다.getView()돌아온다nullonCreateView에서 해 보십시오.onViewCreated방법:

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

당신은 이것을 부르고 있습니다.btn_K너무 빨리 Null을 반환하고 Null 포인터 예외를 제공합니다.

에서 이 가상 플러그인을 사용하여 이러한 보기를 사용할 수 있습니다.onActivityCreated()바로 뒤에 부르는 방법onCreateView()fragment 라이프사이클의.

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

Kotlin Android Extensions 플러그인에 의해 생성된 합성 속성에는 다음이 필요합니다.view위해서Fragment/Activity미리 설정해야 합니다.

당신의 경우,Fragment사용해야 합니다.view.btn_KonViewCreated

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매개 변수는 null이어야 합니다.Bundle? 합성 속성 가져오기를 선택합니다.

특정 레이아웃에 대한 모든 위젯 속성을 한 번에 간편하게 가져올 수 있습니다.

import kotlinx.android.synthetic.main.<layout>.*

따라서 레이아웃 파일 이름이 activity_main.xml이면 다음을 가져옵니다.kotlinx.android.synthetic.main.activity_main.*.

View에서 합성 속성을 호출하려면 다음 항목도 가져와야 합니다.kotlinx.android.synthetic.main.activity_main.view.*.

당신이 해야 할 일은 다음과 같습니다.

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
}

Fragments에 작성된 ActivityCreated에 코드를 입력하십시오.

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()

  }

저의 경우, Otzii의 의견을 따를 때까지 아무 것도 작동하지 않았습니다.치료, 재구축(다시 시작할 필요 없음), 앱을 다시 실행합니다.저도 같이 갈 필요가 없었습니다.onActivityCreated그리고 그냥onCreateView속임수를 썼습니다.

한 번은 잘못된 레이아웃을 부풀리는 오류를 범하여 예상되는 컨트롤을 확실히 얻지 못했습니다.

동반 개체를 정의할 필요가 없습니다. 다음과 같은 보기로 모든 ID를 호출하십시오.

 lateinit var mView: View
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
    mView=inflater.inflate(R.layout.product_list,container,false)

    mView.addProduct.setOnClickListener {

        val intent=Intent(activity,ProductAddActivity::class.java)
        startActivity(intent)
    }     return mView
}

@Egor Neliuba의 대답에 추가하면, 예, 참조 없이 뷰를 호출할 때마다 kotlinex는 rootView를 찾고, 사용자가 fragment와 fragment 안에 있기 때문에 fragment가 없습니다.getView()방법.그러므로 그것은 던질지도 모릅니다.NullPointerException

이를 극복하는 방법은 두 가지가 있습니다.

  • 당신이 오버라이드하거나onViewCreated()전술한 바와 같이
  • 또는 다른 클래스(예: 익명)에서 뷰를 바인딩하려면 다음과 같은 확장 함수를 만들 수 있습니다.

    fun View.bindViews(){...}

두 번째 접근법은 여러 동작을 가진 단일 조각이 있을 때 유용합니다.

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를 사용합니다. -findViewById를 사용하여 Java/kotlin 코드에 대한 요소 형식 xml을 찾은 다음 해당 보기 또는 요소에 대한 작업을 수행해야 합니다.

-그래서 당신이 null 포인터 실행을 받은 이유입니다.

**

언급URL : https://stackoverflow.com/questions/34541650/nullpointerexception-when-trying-to-access-views-in-a-kotlin-fragment

반응형