我试图将我的应用程序从Java转换为Kotlin。
我使用了Android Studio内置转换器并修复了它生成的大部分错误。
对Kotlin来说,这个给我带来了非常艰难的时刻:
我得到了这个用Java编写并被转换的类,显然没有任何错误,这有助于我管理RecyclerView
中的项目点击:
class ItemClickSupport private constructor(private val mRecyclerView: RecyclerView) {
private var mOnItemClickListener: OnItemClickListener? = null
private var mOnItemLongClickListener: OnItemLongClickListener? = null
private val mOnClickListener = View.OnClickListener { v ->
if (mOnItemClickListener != null) {
val holder = mRecyclerView.getChildViewHolder(v)
mOnItemClickListener!!.onItemClicked(mRecyclerView, holder.adapterPosition, v)
}
}
private val mOnLongClickListener = View.OnLongClickListener { v ->
if (mOnItemLongClickListener != null) {
val holder = mRecyclerView.getChildViewHolder(v)
return@OnLongClickListener mOnItemLongClickListener!!.onItemLongClicked(mRecyclerView, holder.adapterPosition, v)
}
false
}
private val mAttachListener = object : RecyclerView.OnChildAttachStateChangeListener {
override fun onChildViewAttachedToWindow(view: View) {
if (mOnItemClickListener != null) {
view.setOnClickListener(mOnClickListener)
}
if (mOnItemLongClickListener != null) {
view.setOnLongClickListener(mOnLongClickListener)
}
}
override fun onChildViewDetachedFromWindow(view: View) {
}
}
init {
mRecyclerView.setTag(R.id.item_click_support, this)
mRecyclerView.addOnChildAttachStateChangeListener(mAttachListener)
}
fun setOnItemClickListener(listener: OnItemClickListener): ItemClickSupport {
mOnItemClickListener = listener
return this
}
fun setOnItemLongClickListener(listener: OnItemLongClickListener): ItemClickSupport {
mOnItemLongClickListener = listener
return this
}
private fun detach(view: RecyclerView) {
view.removeOnChildAttachStateChangeListener(mAttachListener)
view.setTag(R.id.item_click_support, null)
}
interface OnItemClickListener {
fun onItemClicked(recyclerView: RecyclerView, position: Int, v: View)
}
interface OnItemLongClickListener {
fun onItemLongClicked(recyclerView: RecyclerView, position: Int, v: View): Boolean
}
companion object {
fun addTo(view: RecyclerView): ItemClickSupport {
var support: ItemClickSupport? = view.getTag(R.id.item_click_support) as ItemClickSupport
if (support == null) {
support = ItemClickSupport(view)
}
return support
}
fun removeFrom(view: RecyclerView): ItemClickSupport? {
val support = view.getTag(R.id.item_click_support) as ItemClickSupport
support?.detach(view)
return support
}
}
}
在主要活动中,转换后它在onCreate
函数中设置如下:
ItemClickSupport.addTo(recyclerView!!).setOnItemClickListener { recyclerView, position, v ->
val itemIntent = Intent(this@AddSubscription, CreateSubscription::class.java)
...
}
IDE给出了以下错误:
类型不匹配:
必需:ItemClickSupport.OnItemClickListener
找到:(???,???,???) - >单元
现在,我知道Unit
是Kotlin的void
,但我无法弄清楚错误的位置。
按照建议检查this answer后,我编写了以下代码:
ItemClickSupport.addTo(recyclerView!!).setOnItemClickListener(
object: ItemClickSupport.OnItemClickListener {
val itemIntent = Intent(this@AddSubscription, CreateSubscription::class.java)
val bundle = Bundle()
bundle.putParcelable("selected", filteredList!![position])
itemIntent.putExtras(bundle)
startActivity(itemIntent)
})
现在我得到了
预期成员声明
如this other answer中所述,它与构造函数有关。
这是ItemClickSupport.OnItemClickListener构造函数吗?如果是这样,我应该改变什么?
我怀疑错误仍然是由于OnClickSupport
类很难转换为kotlin,即使它没有任何sintax错误
答案 0 :(得分:2)
由于您已将这两个文件都转换为Kotlin,而OnItemClickListener
界面是用Kotlin编写的,因此您无法传递函数lambda。
最好的方法是创建一个匿名的界面实例(你也可以使用lambda,但我为了理解而没有使用lambda发布)
ItemClickSupport.addTo(recyclerView!!)
.setOnItemClickListener (object:OnItemClickListener{
override fun onItemClicked(recyclerView: RecyclerView, position: Int, v: View ){
val itemIntent = Intent(this@AddSubscription, CreateSubscription::class.java)
...
}
})
或者,您可以在ItemClickSupport
中使用HighOrder函数来仅接收lambda并避免接口。