gpt4 book ai didi

android - 在 Kotlin 中创建一个 BaseView 类

转载 作者:行者123 更新时间:2023-11-29 23:19:06 27 4
gpt4 key购买 nike

我正在 Kotlin 中创建一个 BaseView 类,我所有的 subview 都将扩展。

我的问题是在 BaseView 类中膨胀布局,因为布局资源 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 中应用了完全相同的策略,这曾经有效。

我该如何处理这种情况? .我需要在基地中膨胀我的布局。这样做是有道理的,因为通货膨胀是一种常见的操作。

委托(delegate)属性(property)是要走的路吗?

编辑:这是我的客户的样子

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 可能会在某些自定义 View 中出现问题,因为调用为您自己的类生成的任何构造函数将首先委托(delegate)给类中的全参数构造函数,然后调用 super 的全参数构造函数,而不是每个构造函数都使用匹配数量的参数调用 super 方法。参见 this article (例如)了解详情。

关于android - 在 Kotlin 中创建一个 BaseView 类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54743286/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com