【问题标题】:How to initialize widgets in android using kotlin如何使用 kotlin 在 android 中初始化小部件
【发布时间】:2016-09-27 13:58:42
【问题描述】:

我已经开始学习在 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
    }
}

【问题讨论】:

    标签: android nullpointerexception kotlin kotlin-android-extensions


    【解决方案1】:

    !! 操作符检查接收者是否为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()
      

    在最后两种情况下,您无法检查按钮是否为null。如果您需要 null 比较来处理变量,请使用第一种方法。


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

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

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

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

    【讨论】:

    • 那么我该如何初始化我的变量??
    【解决方案2】:

    可以使用 Kotlin 编写 helper 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)
    }
    

    【讨论】:

      【解决方案3】:

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

      1.可空变量

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

      2。延迟初始化

      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.黄油刀

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

      6.小刀

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

      7. Kotlin Android 扩展

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

      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查看每种方法的优缺点

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2021-07-02
        • 1970-01-01
        • 1970-01-01
        • 2023-03-05
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多