Kotlin: How to access the Attrs for a CustomView
You can use core-ktx extension function 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)
}
You cannot access a secondary constructor parameter from an init
block. But there're at least two ways how you can implement similar functionality.
The first approach is using a single primary constructor with default parameters instead of multiple secondary constructors. In this case you have to apply the @JvmOverloads
annotation to the constructor in order to make Kotlin generate three different constructors.
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)
}
}
}
}
An the seconds approach is two chain constructors and move the init block content into the constructor with three arguments.
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)
}
}
}
}
Why don't you simply skip these verbose constructors with default values and do it like that:
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)
}
}