如何使用Kotlin Android扩展与碎片? 如果我在onCreateView()中使用它们,我得到这个NullPointerException异常:

导致:java.lang.NullPointerException:试图调用virtual .lang. nullpointerexception android.view.View. view. findviewbyid (int) ` 空对象引用

下面是片段代码:

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

当前回答

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找到xml到你的java/kotlin代码中的元素,然后只有你可以对该视图或元素执行操作。

-这就是为什么你得到空指针执行

**

其他回答

在Fragments中,请在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()

  }
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找到xml到你的java/kotlin代码中的元素,然后只有你可以对该视图或元素执行操作。

-这就是为什么你得到空指针执行

**

由Kotlin Android Extensions插件生成的合成属性需要一个Fragment/Activity视图来预先设置。

在你的例子中,对于Fragment,你需要使用view。onViewCreated中的btn_K

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参数应该是空的Bundle?,同时勾选导入合成属性

为特定布局导入所有小部件属性非常方便 一口气: 进口kotlinx.android.synthetic.main。> <布局。* 因此,如果布局文件名是activity_main.xml,我们将导入 kotlinx.android.synthetic.main.activity_main。*。 如果我们想在View上调用合成属性,我们也应该这样做 进口kotlinx.android.synthetic.main.activity_main.view。*。

将它添加到@Egor Neliuba的答案中,是的,每当你调用一个没有引用的视图时,kotlinex都会寻找一个rootView,因为你在一个片段中,而片段没有getView()方法。因此,它可能抛出NullPointerException

有两种方法可以克服这一点,

如前所述,要么重写onViewCreated() 或者如果你想在其他类中绑定视图(比如匿名),你可以简单地创建一个像这样的扩展函数, 乐趣View.bindViews(){…}

第二种方法是有用的,当你有一个具有多种行为的片段时。

你调用这个btn_K太快了,因为在那个时候它返回一个空值,并给你一个空指针异常。

你可以通过onActivityCreated()方法中的合成插件来使用这些视图,该方法被调用在Fragment生命周期的onCreateView()之后。

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