我正在尝试在我的Android项目中使用Kotlin语言。我需要创建自定义视图类。每个自定义视图都有两个重要的构造函数:
public class MyView extends View {
public MyView(Context context) {
super(context);
}
public MyView(Context context, AttributeSet attrs) {
super(context, attrs);
}
}
MyView(Context)
用于在代码中实例化视图,MyView(Context, AttributeSet)
在从XML填充布局时被布局膨胀器调用。
回答这个问题的建议是使用具有默认值的构造函数或工厂方法。但以下是我们现在所拥有的:
工厂方法:
fun MyView(c: Context) = MyView(c, attrs) //attrs is nowhere to get
class MyView(c: Context, attrs: AttributeSet) : View(c, attrs) { ... }
或者
fun MyView(c: Context, attrs: AttributeSet) = MyView(c) //no way to pass attrs.
//layout inflater can't use
//factory methods
class MyView(c: Context) : View(c) { ... }
默认值构造函数:
class MyView(c: Context, attrs: AttributeSet? = null) : View(c, attrs) { ... }
//here compiler complains that
//"None of the following functions can be called with the arguments supplied."
//because I specify AttributeSet as nullable, which it can't be.
//Anyway, View(Context,null) is not equivalent to View(Context,AttributeSet)
这个谜题怎么解决?
更新:看起来我们可以使用View(Context, null)
超类构造函数代替View(Context)
,因此工厂方法似乎是解决方案。但即使如此,我仍然无法让我的代码运行:
fun MyView(c: Context) = MyView(c, null) //compilation error here, attrs can't be null
class MyView(c: Context, attrs: AttributeSet) : View(c, attrs) { ... }
或者
fun MyView(c: Context) = MyView(c, null)
class MyView(c: Context, attrs: AttributeSet?) : View(c, attrs) { ... }
//compilation error: "None of the following functions can be called with
//the arguments supplied." attrs in superclass constructor is non-null
AdapterView
子类,调用super(context, null)
是有效的,但我不确定在框架中的所有其他视图类中是否会产生任何副作用,因此最好能够调用特定的超类构造函数。 - Andrii Chernenkoattrs
在超类构造函数中被定义为非空,我不能将null传递给它。 - Andrii Chernenko