我正在Kotlin中创建一个BaseView类,我的所有子视图都将扩展。
我的问题是在BaseView类中夸大Layout,因为布局资源id对于BaseView构造函数来说太迟了。
这是我的BaseView
abstract class BaseView @JvmOverloads constructor(
context: Context?,
attributeSet: AttributeSet? = null,
defStyleAttr: Int = 0
) : MaterialCardView(context, attributeSet, defStyleAttr) {
protected abstract val viewResourceId: Int
protected abstract val needsRefresh: Boolean
init {
View.inflate(context,viewResourceId, this) // viewResourceId is not initialized here as yet
}
enum class State {
DISABLED,
LOADING,
DONE,
FAILED
}
}
问题是众所周知的“在构造函数中访问非最终属性”。我以前在Java中应用了完全相同的策略,这曾经起作用。
我该如何处理这种情况? 。我需要在基地中扩充我的布局。这样做是有道理的,因为通货膨胀是一种常见的操作。
委托财产是否可行?
编辑:这是我的客户看起来的样子
class StudentView @JvmOverloads constructor(
context: Context?,
attributeSet: AttributeSet? = null,
defStyleAttr: Int = 0
) : BaseRegion(context, attributeSet, defStyleAttr) {
override val viewResourceId=R.layout.student_view
override val needsRefresh=false
init {
context?.
let { setCardBackgroundColor(ContextCompat.getColorStateList(context,R.color.colorAccent)!!)}
}
}
当您使用具有支持字段的属性时,这将不起作用,因为该字段的初始化发生在子类的构造函数中,该构造函数在父构造函数之后运行。
但是,您可以使用计算属性,该属性将在父级调用时按预期进行评估:
override val viewResourceId: Int
get() = R.layout.some_layout
或者您可以定义一个抽象函数,并覆盖它,这基本上是相同的:
override fun getViewResourceId(): Int = R.layout.some_layout
另一方面,使用@JvmOverloads
可能是某些自定义视图中的问题,因为调用为您自己的类生成的任何构造函数将首先委托给类中的all-params构造函数,然后调用super的all-params构造函数。而不是每个构造函数使用匹配的参数量调用super方法。有关详细信息,请参阅this article(例如)。