我已经开始学习在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
}
}
答案 0 :(得分:15)
!!
运算符检查接收方是否为null
以及是否抛出KotlinNullPointerException
。因此null!!
将始终抛出异常。
您可以通过以下方式实现目标:
将属性类型设置为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
将按钮设为lateinit
属性。
lateinit var add: Button
将按钮设为notNull
委托属性。
var add: Button by Delegates.notNull()
在最后两种情况下,您无法检查按钮是否为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"
查看每种方法的优惠/缺点