如何使用kotlin在android中初始化小部件

时间:2016-05-29 19:05:28

标签: android nullpointerexception kotlin kotlin-android-extensions

我已经开始学习在android中使用kotlin语言并在初始化我的按钮变量时遇到问题,因为在定义我的变量时,它要求在使用null值初始化时给出一些初始值并在oncreate函数中绑定变量它给出了

  

kotlin.KotlinNullPointerException

这是我的代码

class AddsFragment : Fragment() {

    var Add: Button = null!!

    override fun onCreateView(inflater: LayoutInflater?, container: ViewGroup?, savedInstanceState: Bundle?): View? {
        val Rootview = inflater!!.inflate(R.layout.clubsfragment, null, false)
        Add = Rootview.findViewById(R.id.add) as Button
        return Rootview
    }
}

3 个答案:

答案 0 :(得分:15)

!!运算符检查接收方是否为null以及是否抛出KotlinNullPointerException。因此null!!将始终抛出异常。

您可以通过以下方式实现目标:

  1. 将属性类型设置为Button?。在这种情况下,当访问按钮的方法时,您必须使用?!!

    var add: Button? = null
    // Initialize it somewhere.
    
    add?.setText("Text") // Calls setText if Add != null
    add!!.setText("Text") // Throws an exception if Add == null
    
  2. 将按钮设为lateinit属性。

    lateinit var add: Button
    
  3. 将按钮设为notNull委托属性。

    var add: Button by Delegates.notNull()
    
  4. 在最后两种情况下,您无法检查按钮是否为null。如果您需要进行null比较以使用变量,请使用第一种方法。

    在这个答案中我还没有详细描述其他方法。第一个是使用Kotlin Android Extensions。这是一个编译器插件,可以为您的视图生成合成属性,因此您无需调用findViewById()并可以使用生成的属性访问视图。

    第二种方法是创建自己的代理,为您调用findViewById()。它可能看起来像这样:

    val add: Button by bindView(R.id.add)
    

    您可以在KotterKnife项目中找到此类委托的示例。

答案 1 :(得分:3)

您可以使用Kotlin编写帮助bind函数:

fun <T : View> Activity.bind(@IdRes res : Int) : Lazy<T> {
    @Suppress("UNCHECKED_CAST")    
    return lazy { findViewById(res) as T }
}

然后,您可以使用val(在Java中等于final)简单地定义变量一次:

class MyActivity : AppCompatActivity() {
    private val button: Button by bind(R.id.button)
}

class MyActivity : AppCompatActivity() {
    private val button by bind<Button>(R.id.button)
}

答案 2 :(得分:3)

您可以使用以下任何一种方法在kotlin中初始化视图:

<强> 1。 Nullable vars

private var textView: TextView? = null
…
textView = findViewById(R.id.text_view) as TextView

<强> 2。 lateinit

private lateinit var textView: TextView
…
textView = findViewById(R.id.text_view) as TextView

第3。 Delegates.notNull()

private var textView: TextView by Delegates.notNull()
…
textView = findViewById(R.id.text_view) as TextView

<强> 4。懒惰属性

private val textView: TextView by lazy { findViewById(R.id.text_view) as TextView }

<强> 5。 Butterknife

@BindView(R2.id.text_view)
internal lateinit var textView: TextView

<强> 6。 Kotterknife

private val textView: TextView by bindView(R.id.text_view)

<强> 7。 Kotlin Android Extensions

没有代码示例,只需添加正确的导入并开始使用合成生成的属性,如下所示。

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

<强> 8。 Android数据绑定

binding = FragmentLayoutBinding.inflate(inflater, container, false)
...
binding.textView.text = "Hello"

您可以在Pros/cons of Android view access strategies

查看每种方法的优惠/缺点