我正在 Android 项目中实现一个 SpinnerAdapter
。所以我必须重写 getView(i: Int, convertView: View, parent: ViewGroup)
方法。所以 convertView
在这里是为了重用现有 View 并减少内存使用和 GC 发生。因此,如果它是 null
,我必须创建 View 并使用已经创建的 View 。
所以实际上我必须写这样的东西(google 官方推荐):
if (view == null) {
view = View.inflate(context, R.layout.item_spinner, parent)
view.tag(Holder(view))
} else {
(view.tag as Holder).title.text = getItem(i)
}
但是 Kotlin 不允许写入参数。 我在网上查到的是官方blog post这表示自 2013 年 2 月以来不可能。
所以我想知道是否有任何解决方法?
最佳答案
这里有两个问题。
首先,您错误地假设在 Java 中修改 view
会在当前函数范围之外执行任何操作。它不是。您将该参数设置为新值不会影响局部函数范围之外的任何内容。
View getView(int i, View view, ViewGroup parent) {
// modify view here does nothing to the original caller reference to view
// but returning a view does do something
}
接下来,在 Kotlin 中所有参数都是 final
(JVM 修饰符,也与 Java 中的 final
修饰符相同)。此代码的 Kotlin if
语句版本为:
fun getView(i: Int, view: View?, parent: ViewGroup): View {
return if (view == null) {
val tempView = View.inflate(context, R.layout.item_spinner, parent)
tempView.tag(Holder(tempView))
tempView
} else {
(view.tag as Holder).title.text = getItem(i)
view
}
}
或者避免新的局部变量:
fun getView(i: Int, view: View?, parent: ViewGroup): View {
return if (view == null) {
View.inflate(context, R.layout.item_spinner, parent).apply {
tag(Holder(this)) // this is now the new view
}
} else {
view.apply { (tag as Holder).title.text = getItem(i) }
}
}
或
fun getView(i: Int, view: View?, parent: ViewGroup): View {
if (view == null) {
val tempView = View.inflate(context, R.layout.item_spinner, parent)
tempView.tag(Holder(tempView))
return tempView
}
(view.tag as Holder).title.text = getItem(i)
return view
}
或使用 ?.
和 ?:
空运算符结合 apply()
:
fun getView(i: Int, view: View?, parent: ViewGroup): View {
return view?.apply {
(tag as Holder).title.text = getItem(i)
} ?: View.inflate(context, R.layout.item_spinner, parent).apply {
tag(Holder(this))
}
}
还有另外 10 种变体,但您可以尝试看看自己喜欢什么。
通过使用相同的名称来隐藏变量被认为不是一个好的做法(但允许),这就是为什么它是一个编译器警告。以及为什么您看到上面的变量名从 view
更改为 tempView
关于android - 如何在 Kotlin 中使方法参数可变?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44109098/