如何使用 kotlin 在 android 中初始化小部件
Posted
技术标签:
【中文标题】如何使用 kotlin 在 android 中初始化小部件【英文标题】:How to initialize widgets in android using kotlin 【发布时间】: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
【问题讨论】:
【参考方案1】:!!
操作符检查接收者是否为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 项目中找到此类委托的示例。
【讨论】:
那么我该如何初始化我的变量??【参考方案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查看每种方法的优缺点
【讨论】:
以上是关于如何使用 kotlin 在 android 中初始化小部件的主要内容,如果未能解决你的问题,请参考以下文章
如何在 Kotlin 中为 Android 的 RecyclerView 适配器初始化 viewHolder
如何在 Kotlin 类中声明一个公共值 (val) 以便稍后对其进行初始化。在这种特殊情况下不能使用 var
使用 Kotlin 在 android 中声明 UI 组件的最佳方法是啥?