Jeremi
Jeremi

Reputation: 1474

Understanding styles

I'm trying to set a custom colour for my buttons in Android application but value set for accentColor is always used as button background colour. I am trying to set a global colour for all buttons without having to specify styles or theme for each button individually.

Can you explain please how styling works in Android? I understand the basics, but overriding existing themes is never working for me :(

styles.xml

<resources>

<style name="AppTheme" parent="Theme.MaterialComponents.Light.NoActionBar">
    <item name="colorPrimary">@color/colorPrimary</item>
    <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
    <item name="colorAccent">@color/colorAccent</item>
    <item name="android:titleTextColor">#ffffff</item>
    <item name="android:buttonStyle">@style/AppTheme.Button</item>

</style>

<style name="AppTheme.NoActionBar">
    <item name="windowActionBar">false</item>
    <item name="windowNoTitle">true</item>
</style>

<style name="AppTheme.Button" >
    <item name="android:backgroundTint">@color/colorPrimaryDark</item>
</style>

<style name="AppTheme.AppBarOverlay" parent="ThemeOverlay.AppCompat.Dark.ActionBar" />

<style name="AppTheme.PopupOverlay" parent="ThemeOverlay.AppCompat.Light" />

Upvotes: 0

Views: 117

Answers (2)

Jeremi
Jeremi

Reputation: 1474

I managed to solve the issue. The main point to notice here is that I am using Theme.MaterialComponents and not AppCompact.

I have defined a new style and I set it to buttonStyle, which refers to style for AppCompact button. In order to set a style for the material button, I had to use "materialButtonStyle" instead of "buttonStyle".

All relevant properties that can be overridden for MaterialComponents can be found in material design documentation: https://www.material.io/develop/android/components/material-button/

So the final code looks like this:

<resources>

    <!-- Base application theme. -->
    <style name="AppTheme" parent="Theme.MaterialComponents.Light.NoActionBar">
        <!-- Customize your theme here. -->
        <item name="colorPrimary">@color/colorPrimary</item>
        <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
        <item name="colorAccent">@color/colorAccent</item>
        <item name="colorSecondary">@color/colorAccent</item>
        <item name="floatingActionButtonStyle">@style/AppTheme.Test</item>
        <item name="materialButtonStyle">@style/AppTheme.Button</item>
        <!--<item name="buttonStyle">@style/Widget.MaterialComponents.Button.Icon</item>-->
    </style>

    <style name="AppTheme.Button" parent="@style/Widget.MaterialComponents.Button">
        <item name="android:backgroundTint">#D400EB</item>
    </style>
    <style name="AppTheme.Test" parent="@style/Widget.MaterialComponents.FloatingActionButton">
        <item name="backgroundTint">#A305B1</item>
    </style>

    <style name="AppTheme.NoActionBar">
        <item name="windowActionBar">false</item>
        <item name="windowNoTitle">true</item>
    </style>
    <style name="AppTheme.AppBarOverlay" parent="ThemeOverlay.AppCompat.Dark.ActionBar"/>
    <style name="AppTheme.PopupOverlay" parent="ThemeOverlay.AppCompat.Light"/>

</resources>

Upvotes: 1

Benny
Benny

Reputation: 1738

Short answer: Try going to the source code of how the Theme.MaterialComponents.Light.NoActionBar is defining the style for the buttons and override those attributes.

Android styling works by merging all the defined attributes in a theme. For example, you have an AppTheme that includes theming for every built-in view. If you create a new theme for your button and your define just a couple of attributes, what android studio does is to merge all the attributes defined in the AppTheme with your new attributes. So if you want to override the buttons, you need to go deep and find out what are exactly the attributes defined in the general AppTheme you set in your application, they may not be the same.

For example, this is how I changed the color of all the buttons in my app since they were using a global attribute for it: In the general styles.xml file, I put:

<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
    ...
    <item name="colorButtonNormal">?myCustomColor</item>
    ...
</style>

But if I wanted to change the backgroundTint attribute of my buttons, I had to do this:

<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
    ...
    <item name="colorButtonNormal">?myCustomColor</item>
    <item name="android:buttonStyle">@style/AppButtonStyle</item>
    ...
</style>

<style name="AppButtonStyle" parent="Widget.AppCompat.Button">
    <item name="android:backgroundTint">?attr/colorAccent</item>
</style>

Also, check out this cool Medium post for another developer experience in this topic.

Upvotes: 1

Related Questions