【发布时间】:2014-01-07 09:07:11
【问题描述】:
我正在尝试在我的 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膨胀布局时被布局膨胀器调用。
this question 的回答建议我使用带有默认值或工厂方法的构造函数。但这就是我们所拥有的:
工厂方法:
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
【问题讨论】:
-
在您的工厂方法中,您说 attrs 无处可去,但阻止您传递 null 而不是 attrs?
-
@AndreyBreslav 通常在定义 Android 视图子类构造函数时,我们会调用相应的超类构造函数(如 Java 示例所示)。调用
super(context, null)对AdapterView子类有效,但我不确定框架中的所有其他视图类不会有任何副作用,因此能够调用特定的超类构造函数会很好。跨度> -
@AndreyBreslav 请查看更新。好像你是对的,因为
attrs在超类构造函数中被定义为非空值,所以我不能将空值传递给它。 -
在目前的 Kotlin 状态下似乎不能很好地解决这个问题,但是您可以尝试默认传递一个空的 AttributeSet 实例...
标签: android constructor kotlin