我正在Android项目中实现SpinnerAdapter
。所以我必须覆盖getView(i: Int, convertView: View, parent: ViewGroup)
方法。所以convertView
在这里是为了重用现有视图并减少内存使用和GC出现。因此,如果它是null
我必须创建视图并使用已经创建的其他方式。
所以实际上我必须写这样的东西(官方推荐谷歌):
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不允许写入param。 我在互联网上找到的是一名官员blog post,表示自2013年2月以来不可能。
所以我想知道是否有任何解决方法?
答案 0 :(得分:3)
这里有两个问题。
首先,您错误地认为在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
}
或使用?.
和?:
null运算符与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
答案 1 :(得分:0)
Kotlin支持不的可变参数。
答案 2 :(得分:0)
官方说来,您不能覆盖方法参数。你能做的最好的就是“影子”param变量。
所以你可以这样做(不知道为什么你会想要阴影,但你可以)
getView(i: Int, view: View?, parent: ViewGroup) {
val view = view ?: View.inflate(context, R.layout.item_spinner, parent)
.apply { tag(Holder(view)) }
(view.tag as Holder).title.text = getItem(i)
}
答案 3 :(得分:-1)
实现这一目标有一种肮脏但有用的方法。
fun a(b: Int) {
var b = b
b++ // this compiles
}