Kotlin向Adapter传入this时提示类型不匹配 要求参数为Activity类型
问题说明
Android Kotlin开发中,向自定义ShoeAdapter传入this作为上下文参数时触发编译报错:类型不匹配,要求传入的参数类型为Activity。
相关实现代码
业务代码
val shoeid = arrayOf( "Nike air","Adidas","asics" ) val progress = intArrayOf( 10,50,60 ) shoeArrayList = ArrayList() for ( i in shoeid.indices ) { val shoe = UserShoes(shoeid[i], progress[i]) shoeArrayList.add(shoe) } binding.listviewProfile.adapter = ShoeAdapter(this,shoeArrayList)
数据类定义
data class UserShoes(var shoeName: String, var usage: Int)
自定义Adapter代码
class ShoeAdapter(private val context: Activity,private val arrayList: ArrayList<UserShoes>): ArrayAdapter<UserShoes>(context, R.layout.list_view,arrayList) { override fun getView(position: Int, convertView: View?, parent: ViewGroup): View { val inflater: LayoutInflater = LayoutInflater.from(context) val view: View = inflater.inflate(R.layout.list_view, null) val shoe: TextView = view.findViewById(R.id.shoeID) val progress: ProgressBar = view.findViewById(R.id.progressID) shoe.text = arrayList[position].shoeName progress.progress = arrayList[position].usage return super.getView(position, convertView, parent) } }
报错原因
- Adapter构造函数把上下文参数类型写死成了
Activity:ArrayAdapter的构造方法本来只需要传入Context类型参数,强制要求传Activity相当于抬高了类型校验门槛,只要this指向的实例不是Activity类型(比如在Fragment、点击回调里写this)就会直接报类型不匹配。 this指向不对:如果初始化Adapter的代码不是直接写在Activity类的作用域里(比如写在Fragment生命周期方法、点击事件匿名对象、协程代码块、嵌套内部类中),this不会指向当前的Activity实例,自然匹配不上Activity类型的形参。- 附带逻辑bug:当前
getView方法里自己inflate了自定义列表项布局,最后却返回super.getView()的结果,前面写的控件绑定逻辑完全不会生效,列表加载会出问题。
修复方法
- 第一步:调整Adapter构造函数的上下文类型,将
Activity替换为更通用的Context,符合ArrayAdapter的参数要求,降低传参限制。 - 第二步:根据代码所在位置正确传入上下文:
- 代码写在Activity的onCreate/成员方法中:直接传
this即可 - 代码写在Fragment中:传
requireContext()或者requireActivity() - 代码写在嵌套回调/协程/匿名内部类中:使用带标签的this指定Activity实例,比如
this@你的Activity类名
- 代码写在Activity的onCreate/成员方法中:直接传
- 第三步:修正getView方法的返回值,返回自行inflate的
view对象,不要返回super的结果。
修复后的Adapter代码
class ShoeAdapter(private val context: Context, private val arrayList: ArrayList<UserShoes>): ArrayAdapter<UserShoes>(context, R.layout.list_view, arrayList) { override fun getView(position: Int, convertView: View?, parent: ViewGroup): View { val inflater: LayoutInflater = LayoutInflater.from(context) val view: View = inflater.inflate(R.layout.list_view, null) val shoe: TextView = view.findViewById(R.id.shoeID) val progress: ProgressBar = view.findViewById(R.id.progressID) shoe.text = arrayList[position].shoeName progress.progress = arrayList[position].usage return view } }
内容的提问来源于stack exchange,提问作者Frederico Nicola
相关产品推荐
相关产品推荐

