Kotlin:如何访问CustomView的Attrs

Ely*_*lye 13 android android-custom-view kotlin

我在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)
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

请注意,这将attrs在init函数中出错.我想知道如何访问attrs

Mic*_*ael 16

您无法从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)
      }
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

秒方法是两个链构造函数,并使用三个参数将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)
      }
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

  • 使用完后应该使用 *a.recycle()* 。 (2认同)

Sab*_*aba 7

您可以使用 core-ktx 扩展功能withStyledAttributeshttps://android.github.io/android-ktx/core-ktx/androidx.content/android.content.-context/with-styled-attributes.html

context.withStyledAttributes(set, R.styleable.custom_card_view) {
    val myString = getString(R.styleable.custom_card_view_command)
}
Run Code Online (Sandbox Code Playgroud)


mlt*_*chr 6

为什么不直接跳过这些带有默认值的冗长构造函数并这样做:

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)
    }
}
Run Code Online (Sandbox Code Playgroud)