java.lang.NoSuchMethodException: com.XXX. [class android.content.Context, interface android.util.AttributeSet] ,kotlin 自定义View
有新学习kotlin的小伙伴,可能在自定义view时遇到了这个问题,首先说这个问题的原因,是因为自己实现的view没有重载这个方法
public View(Context context, AttributeSet attrs) {
super(context, attrs);
}
在XML中引入view,这个是必须的。如果你没有重载请参考以下代码,在kotlin中实现
class myViewTest:View{
constructor(context: Context?):super(context){}
constructor(context: Context?, attrs: AttributeSet?):super(context,attrs){}
constructor(context: Context?, attrs: AttributeSet?, defStyleAttr: Int):super(context,attrs,defStyleAttr){}
}
此外如果你是因为使用@JvmOverloads而发生上述错误,那么你可能是因为,没有真正理解这个注解的含义,或者在书上以及其他资料上学习时,有所遗漏。接下来分析下:
class myViewTest @JvmOverloads constructor(context: Context?, attrs: AttributeSet?=null) :
View(context, attrs) {
}
有些教授kotlin编写安卓的书籍提到了上述代码,但是并未过多解释@JvmOverloads的机制,导致自己写如下代码时,仍然发生了题目的错误
class myViewTest @JvmOverloads constructor(context: Context?, attrs: AttributeSet?=null, defStyleAttr: Int) :
View(context, attrs, defStyleAttr) {
}
首先,我们看下关于@JvmOverloads的官方说明
Instructs the Kotlin compiler to generate overloads for this function that substitute default parameter values.
If a method has N parameters and M of which have default values, M overloads are generated: the first one takes N-1 parameters (all but the last one that takes a default value), the second takes N-2 parameters, and so on.
从官方说明我们知道了问题所在,如果一个方法有N个参数,其中M个参数有默认值,那么就会生成M个重载,也就是说,有几个默认值,便会有几个重载,这也是上述代码报错的原因。所以正确代码如下:
class myViewTest @JvmOverloads constructor(context: Context?, attrs: AttributeSet?=null, defStyleAttr: Int=0) :
View(context, attrs, defStyleAttr) {
}