Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Kotlin: How to access the Attrs for a CustomView

Tags:

I create a custom view in Kotlin, and would like to access it's Attributes Resource.

Below is my code

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)             }         }     } } 

Note that this will error in the attrs in the init function. I'm wondering how to access the attrs?

like image 873
Elye Avatar asked Apr 19 '16 11:04

Elye


People also ask

What is customized view?

A well-designed custom view is much like any other well-designed class. It encapsulates a specific set of functionality with an easy to use interface, it uses CPU and memory efficiently, and so on. In addition to being a well-designed class, though, a custom view should: Conform to Android standards.

What is AttributeSet?

AttributeSet (Android Docs)A collection of attributes, as found associated with a tag in an XML document. Basically if you are trying to create a custom view, and you want to pass in values like dimensions, colors etc, you can do so with AttributeSet .


1 Answers

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)       }     }   } } 
like image 194
Michael Avatar answered Oct 06 '22 05:10

Michael