Providing a default style (attributes) in a custom view

android, background, styles, view, widget

Solution

Really late to the party here. But in case someone stumbles upon the same problem, here is my solution.

Let's say we want to have a custom view that extends a `TextInputLayout`. Here's what the class would typically look like:

class MyTextInputLayout: TextInputLayout {
    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)
}

Now, in order to use our custom style as default, change the third constructor (the one with three arguments) into this:

class MyTextInputLayout: TextInputLayout {
    constructor(context: Context) : this(context, null)
    constructor(context: Context, attrs: AttributeSet?) : this(context, attrs, 0)
    constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int)
        : super(ContextThemeWrapper(context, R.style.MyTextInputLayoutStyle), attrs, defStyleAttr)
}

Now we can use the custom view in a layout XML file like this:

<com.xxx.MyTextInputLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content">

we no longer need to define `style="@style/MyTextInputLayoutStyle"` in the component.

In short, we need to replace the `context` passed to the super constructor with the one that wraps our style. This way we don't need to define R.attr.MyTextInputLayoutStyle in the existing theme. Useful when you want to use the custom view as a library.

Problem

Please, let me know, how can I set the default background of a custom button to null. I mean... I know I can define a "style" which set android:background to "@null", and ask users to explicitly apply the style in their layout. For example: ``` <style name="MyButton" parent="@android:style/Widget.Button"> <item name="android:background">@null</item> </style> ``` and ``` <com.xxx.widget.MyButton android:layout_width="match_parent" android:layout_height="wrap_content" style="@style/MyButton" android:text="MyButton" /> ``` Above code is working well. But how can I apply this style in my class "MyButton" internally and let users not to set style explicitly? For example, how to make following layout works as before: ``` <com.xxx.widget.MyButton android:layout_width="match_parent" android:layout_height="wrap_content" android:text="MyButton" /> ``` I tried to do this in the constructor as below, but its not working. ``` public MyButton(Context context, AttributeSet attrs) { this(context, attrs, com.xxx.R.style.MyButton); } ``` PS. I want to apply this "null" background when a user does not set the background explicitly.

Original source

Related problems