Kotlin:如何访问 CustomView 的属性
Kotlin: How to access the Attrs for a CustomView
我在 Kotlin 中创建了一个自定义视图,并想访问它的属性资源。
下面是我的代码
class CustomCardView : FrameLayout {
constructor(context: Context) : super(context)
constructor(context: Context, attrs: AttributeSet) : super(context, attrs)
constructor(context: Context, attrs: AttributeSet, defStyleAttr: Int) : super(context, attrs, defStyleAttr)
init {
LayoutInflater.from(context).inflate(R.layout.view_custom_card, this, true)
if (attrs != null) {
val a = context.obtainStyledAttributes(attrs, R.styleable.custom_card_view)
if (a.hasValue(R.styleable.custom_card_view_command)) {
var myString = a.getString(R.styleable.custom_card_view_command)
}
}
}
}
注意这会在init函数的attrs
中出错。我想知道如何访问 attrs
?
您不能从 init
块访问辅助构造函数参数。但是至少有两种方法可以实现类似的功能。
第一种方法是使用带有默认参数的单个主构造函数,而不是多个辅助构造函数。在这种情况下,您必须将 @JvmOverloads
注释应用于构造函数,以使 Kotlin 生成三个不同的构造函数。
class CustomCardView @JvmOverloads constructor(
context: Context,
attrs: AttributeSet? = null,
defStyleAttr: Int = 0
) : FrameLayout {
init {
LayoutInflater.from(context).inflate(R.layout.view_custom_card, this, true)
if (attrs != null) {
val a = context.obtainStyledAttributes(attrs, R.styleable.custom_card_view)
if (a.hasValue(R.styleable.custom_card_view_command)) {
var myString = a.getString(R.styleable.custom_card_view_command)
}
}
}
}
第二个方法是两个链式构造函数,并将 init 块内容移动到具有三个参数的构造函数中。
class CustomCardView : FrameLayout {
constructor(context: Context) :
this(context, null)
constructor(context: Context, attrs: AttributeSet) :
this(context, attrs, 0)
constructor(context: Context, attrs: AttributeSet, defStyleAttr: Int) :
super(context, attrs, defStyleAttr) {
LayoutInflater.from(context).inflate(R.layout.view_custom_card, this, true)
if (attrs != null) {
val a = context.obtainStyledAttributes(attrs, R.styleable.custom_card_view)
if (a.hasValue(R.styleable.custom_card_view_command)) {
var myString = a.getString(R.styleable.custom_card_view_command)
}
}
}
}
调整你的代码,我想你也可以这样做:
class CustomCardView(context: Context, attrs: AttributeSet?, defStyleAttr: Int) :
FrameLayout(context, attrs, defStyleAttr) {
constructor(context: Context) : this(context, null)
constructor(context: Context, attrs: AttributeSet?) : this(context, attrs, 0)
init {
LayoutInflater.from(context).inflate(R.layout.view_custom_card, this, true)
if (attrs != null) {
val a = context.obtainStyledAttributes(attrs, R.styleable.custom_card_view)
if (a.hasValue(R.styleable.custom_card_view_command)) {
var myString = a.getString(R.styleable.custom_card_view_command)
}
a.recycle()
}
}
}
这有点冗长,但在所有条件下都应该按预期工作:
import android.content.Context
import android.util.AttributeSet
import android.view.LayoutInflater
import android.widget.FrameLayout
class CustomCardView: FrameLayout {
constructor(context: Context) : super(context) {
initialize(context, null)
}
constructor(context: Context, attrs: AttributeSet) : super(context, attrs) {
initialize(context, attrs)
}
constructor(context: Context, attrs: AttributeSet, defStyleAttr: Int) : super(context, attrs, defStyleAttr) {
initialize(context, attrs)
}
private fun initialize(context: Context, attrs: AttributeSet?) {
LayoutInflater.from(context).inflate(R.layout.view_custom_card, this, true)
attrs?.let {
val a = context.obtainStyledAttributes(it, R.styleable.custom_card_view)
if (a.hasValue(R.styleable.custom_card_view_command)) {
var myString = a.getString(R.styleable.custom_card_view_command)
}
}
}
}
你为什么不简单地跳过这些带有默认值的冗长构造函数并像那样做:
class CustomCardView @JvmOverloads constructor(
context: Context,
attrs: AttributeSet? = null,
defStyleAttr: Int = 0
) : FrameLayout(context, attrs, defStyleAttr) {
init {
inflate(context, R.layout.view_custom_card, this)
attrs?.let {
val typedArray = context.obtainStyledAttributes(it, R.styleable.custom_card_view)
val myString = typedArray.getString(R.styleable.custom_card_view_command)
}
}
可以使用core-ktx扩展功能withStyledAttributes
(https://android.github.io/android-ktx/core-ktx/androidx.content/android.content.-context/with-styled-attributes.html)
context.withStyledAttributes(set, R.styleable.custom_card_view) {
var myString = getString(R.styleable.custom_card_view_command)
}
我在 Kotlin 中创建了一个自定义视图,并想访问它的属性资源。
下面是我的代码
class CustomCardView : FrameLayout {
constructor(context: Context) : super(context)
constructor(context: Context, attrs: AttributeSet) : super(context, attrs)
constructor(context: Context, attrs: AttributeSet, defStyleAttr: Int) : super(context, attrs, defStyleAttr)
init {
LayoutInflater.from(context).inflate(R.layout.view_custom_card, this, true)
if (attrs != null) {
val a = context.obtainStyledAttributes(attrs, R.styleable.custom_card_view)
if (a.hasValue(R.styleable.custom_card_view_command)) {
var myString = a.getString(R.styleable.custom_card_view_command)
}
}
}
}
注意这会在init函数的attrs
中出错。我想知道如何访问 attrs
?
您不能从 init
块访问辅助构造函数参数。但是至少有两种方法可以实现类似的功能。
第一种方法是使用带有默认参数的单个主构造函数,而不是多个辅助构造函数。在这种情况下,您必须将 @JvmOverloads
注释应用于构造函数,以使 Kotlin 生成三个不同的构造函数。
class CustomCardView @JvmOverloads constructor(
context: Context,
attrs: AttributeSet? = null,
defStyleAttr: Int = 0
) : FrameLayout {
init {
LayoutInflater.from(context).inflate(R.layout.view_custom_card, this, true)
if (attrs != null) {
val a = context.obtainStyledAttributes(attrs, R.styleable.custom_card_view)
if (a.hasValue(R.styleable.custom_card_view_command)) {
var myString = a.getString(R.styleable.custom_card_view_command)
}
}
}
}
第二个方法是两个链式构造函数,并将 init 块内容移动到具有三个参数的构造函数中。
class CustomCardView : FrameLayout {
constructor(context: Context) :
this(context, null)
constructor(context: Context, attrs: AttributeSet) :
this(context, attrs, 0)
constructor(context: Context, attrs: AttributeSet, defStyleAttr: Int) :
super(context, attrs, defStyleAttr) {
LayoutInflater.from(context).inflate(R.layout.view_custom_card, this, true)
if (attrs != null) {
val a = context.obtainStyledAttributes(attrs, R.styleable.custom_card_view)
if (a.hasValue(R.styleable.custom_card_view_command)) {
var myString = a.getString(R.styleable.custom_card_view_command)
}
}
}
}
调整你的代码,我想你也可以这样做:
class CustomCardView(context: Context, attrs: AttributeSet?, defStyleAttr: Int) :
FrameLayout(context, attrs, defStyleAttr) {
constructor(context: Context) : this(context, null)
constructor(context: Context, attrs: AttributeSet?) : this(context, attrs, 0)
init {
LayoutInflater.from(context).inflate(R.layout.view_custom_card, this, true)
if (attrs != null) {
val a = context.obtainStyledAttributes(attrs, R.styleable.custom_card_view)
if (a.hasValue(R.styleable.custom_card_view_command)) {
var myString = a.getString(R.styleable.custom_card_view_command)
}
a.recycle()
}
}
}
这有点冗长,但在所有条件下都应该按预期工作:
import android.content.Context
import android.util.AttributeSet
import android.view.LayoutInflater
import android.widget.FrameLayout
class CustomCardView: FrameLayout {
constructor(context: Context) : super(context) {
initialize(context, null)
}
constructor(context: Context, attrs: AttributeSet) : super(context, attrs) {
initialize(context, attrs)
}
constructor(context: Context, attrs: AttributeSet, defStyleAttr: Int) : super(context, attrs, defStyleAttr) {
initialize(context, attrs)
}
private fun initialize(context: Context, attrs: AttributeSet?) {
LayoutInflater.from(context).inflate(R.layout.view_custom_card, this, true)
attrs?.let {
val a = context.obtainStyledAttributes(it, R.styleable.custom_card_view)
if (a.hasValue(R.styleable.custom_card_view_command)) {
var myString = a.getString(R.styleable.custom_card_view_command)
}
}
}
}
你为什么不简单地跳过这些带有默认值的冗长构造函数并像那样做:
class CustomCardView @JvmOverloads constructor(
context: Context,
attrs: AttributeSet? = null,
defStyleAttr: Int = 0
) : FrameLayout(context, attrs, defStyleAttr) {
init {
inflate(context, R.layout.view_custom_card, this)
attrs?.let {
val typedArray = context.obtainStyledAttributes(it, R.styleable.custom_card_view)
val myString = typedArray.getString(R.styleable.custom_card_view_command)
}
}
可以使用core-ktx扩展功能withStyledAttributes
(https://android.github.io/android-ktx/core-ktx/androidx.content/android.content.-context/with-styled-attributes.html)
context.withStyledAttributes(set, R.styleable.custom_card_view) {
var myString = getString(R.styleable.custom_card_view_command)
}