I have a custom layout as below
class CustomComponent : FrameLayout {
constructor(context: Context?) : super(context)
constructor(context: Context?, attrs: AttributeSet?) : super(context, attrs) {
initAttrs(attrs)
}
constructor(context: Context?, attrs: AttributeSet?, defStyleAttr: Int) : super(context, attrs, defStyleAttr) {
initAttrs(attrs)
}
constructor(context: Context?, attrs: AttributeSet?, defStyleAttr: Int, defStyleRes: Int) : super(context, attrs, defStyleAttr, defStyleRes) {
initAttrs(attrs)
}
init {
LayoutInflater.from(context).inflate(R.layout.view_custom_component, this, true)
}
fun initAttrs(attrs: AttributeSet?) {
val typedArray = context.obtainStyledAttributes(attrs, R.styleable.custom_component_attributes, 0, 0)
my_title.text = resources.getText(typedArray
.getResourceId(R.styleable.custom_component_attributes_custom_component_title, R.string.component_one))
typedArray.recycle()
}
}
Now for each constructor, I have to explicitly call initAttrs(attrs)
as I can't find way to access attrs
in my init
function.
Is there a way I could access attrs
in init
function, so I could call initAttrs(attrs)
from init
instead of having to explicitly call it in each of the constructor?
Constructors can be passed as arugments to methods using a method reference, somewhat like a function pointer in C++. This can be a Function type with one argument or a BiFunction type with two arguments, either way its a lambda returning a class of the type it constructs.
This method has four parameters: the loan amount, the interest rate, the future value and the number of periods. The first three are double-precision floating point numbers, and the fourth is an integer.
Argument Names When you declare an argument to a method or a constructor, you provide a name for that argument. This name is used within the method body to refer to the data. The name of an argument must be unique in its scope.
Remember, every class must have a constructor, even if it only relies on the default constructor.
Use a constructor with default arguments:
class CustomComponent @JvmOverloads constructor(
context: Context,
attrs: AttributeSet? = null,
defStyle: Int = 0
) : FrameLayout(context, attrs, defStyle) {
fun init {
// Initialize your view
}
}
The @JvmOverloads
annotation tells Kotlin to generate three overloaded constructors so they can be called in Java as well.
In your init
function, attrs
becomes available as a nullable type:
fun init {
LayoutInflater.from(context).inflate(R.layout.view_custom_component, this, true)
attrs?.let {
val typedArray = context.obtainStyledAttributes(it, R.styleable.custom_component_attributes, 0, 0)
my_title.text = resources.getText(typedArray
.getResourceId(R.styleable.custom_component_attributes_custom_component_title, R.string.component_one))
typedArray.recycle()
}
}
Note the usage of it
in the let
block.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With