如何使用 kotlin 在 android 中初始化小部件
How to initialize widgets in android using kotlin
我已经开始在 android 中学习使用 kotlin 语言并在初始化我的按钮变量时遇到问题,因为在定义我的变量时它要求在我用空值初始化时给出一些初始值并且在 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
}
}
!!
运算符检查接收者是否 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 项目中找到此类委托的示例。
您可以使用 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)
}
您可以使用以下任何一种方法在 kotlin 中初始化视图:
1.可空变量
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.黄油刀
@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"
查看每个方法的 pro/cons
我已经开始在 android 中学习使用 kotlin 语言并在初始化我的按钮变量时遇到问题,因为在定义我的变量时它要求在我用空值初始化时给出一些初始值并且在 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
}
}
!!
运算符检查接收者是否 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 项目中找到此类委托的示例。
您可以使用 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)
}
您可以使用以下任何一种方法在 kotlin 中初始化视图:
1.可空变量
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.黄油刀
@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"
查看每个方法的 pro/cons