Reputation: 2891
I want to implement custom style for view. Let's take an example of button. Some common values will be shared across the app for that I am using style like below:
<style name="Widget.Demo.Button.Primary" parent="@style/Widget.MaterialComponents.Button">
<item name="fontFamily">@font/roboto</item>
<item name="android:fontFamily">@font/roboto</item>
<item name="android:minHeight">64dp</item>
<item name="android:theme">@style/ThemeOverlay.Demo.GrayPrimary</item>
</style>
<style name="ThemeOverlay.Demo.GrayPrimary" parent="">
<item name="colorPrimary">@color/gray</item>
</style>
Now I want to add some of the custom attribute in the button like below (This is just an example not the real attribute):
<com.android.CustomButton
android:id="@+id/btn_first"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/first"
app:abc="primary"
style="@style/Widget.Demo.Button.Primary"/>
attrs.xml:
<declare-styleable name="CustomButtonAttr" >
<attr name="abc" format="enum" >
<enum name="primary" value="1"/>
<enum name="secondary" value="2"/>
</declare-styleable>
I don't want to define style and custom attribute in xml everytime. Is there any way to get custom attribute directly in my customview and Widget.Demo.Button.Primary
set by default in my below class?
class CustomButton : MaterialButton {
constructor(context: Context) : super(context)
constructor(context: Context, attributeSet: AttributeSet) : super(
ThemeEnforcement.createThemedContext(context, attributeSet, 0, 0),
attributeSet,
0
)
}
I don't want to define style in xml for every button or view which I create. So is there a way to define in CustomButton
class along with custom attributes ? If yes could you please give me some references.
Thanks in advance.
Upvotes: 0
Views: 382
Reputation: 15334
Yep, you can use the default style attribute in the constructor.
Define a new attribute:
<attr name="customButtonStyle" format="reference" />
Then use the appropriate view constructor:
private val defStyleAttr = R.attr.customButtonStyle
class CustomButton(context: Context, attrs: AttributeSet) : MaterialButton(
ThemeEnforcement.createThemedContext(context, attributeSet, defStyleAttr, 0),
attributeSet,
defStyleAttr
) {
init {
val typedArray = context.obtainStyledAttributes(
attrs,
R.styleable.CustomButton,
defStyleAttr,
0
)
...
}
In your theme, point customButtonStyle
to the style resource that you want used by default:
<style name="Theme.Demo" parent="Base.Theme.Demo">
<item name="customButtonStyle">@style/Widget.Demo.Button.Primary</item>
</style>
Note that android:theme
should be changed to materialThemeOverlay
in that style resource, as it won't be applied when read from a default style. As you're already wrapping the context with the ThemeEnforcement
function (newer versions of Material Design Components change this to MaterialThemeOverlay
), this custom view supports materialThemeOverlay
👍
You can add your custom attributes to the style too:
<style name="Widget.Demo.Button.Primary" parent="@style/Widget.MaterialComponents.Button">
<item name="abc">primary</item>
<item name="fontFamily">@font/roboto</item>
<item name="android:fontFamily">@font/roboto</item>
<item name="android:minHeight">64dp</item>
<item name="materialThemeOverlay">@style/ThemeOverlay.Demo.GrayPrimary</item>
</style>
Upvotes: 1