0

New to AS. Trying to use MaterialButton, overriding default background with @drawable, but it's not working.

Environment Android Studio: 4.0 Dependencies: implementation "androidx.appcompat:appcompat:$dependency_version_appcompat" implementation "com.google.android.material:material:$dependency_version_material"

Drawable

<shape xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:shape="rectangle">
    <solid
            app:backgroundTint ="?attr/ColorBackgroundAppBar">
    </solid>
    <stroke
            android:width="1px"
            android:color="?attr/ColorBorderDark">
    </stroke>
</shape>

Layout

<com.google.android.material.button.MaterialButton
android:id="@+id/common_appbar_btn_lang_mode"
android:layout_width="50dp"
android:layout_height="50dp"
android:layout_centerInParent="true"
android:background = "@drawable/common_appbar_btn_background"
android:elevation="@dimen/common_elevation_height_btn"
... />

With the above, I just get the default MaterialButton background.

If I set backgroundTint to @null

<com.google.android.material.button.MaterialButton
android:id="@+id/common_appbar_btn_lang_mode"
android:layout_width="50dp"
android:layout_height="50dp"
android:layout_centerInParent="true"
app:backgroundTint="@null"
android:background = "@drawable/common_appbar_btn_background"
android:elevation="@dimen/common_elevation_height_btn"
... />

With the above, the drawable specs are recognized, but if I change the theme style, that doesn't work.

These are the only settings that work:

<com.google.android.material.button.MaterialButton
android:id="@+id/common_appbar_btn_lang_mode"
android:layout_width="50dp"
android:layout_height="50dp"
android:layout_centerInParent="true"
android:backgroundTint = "?attr/ColorBackgroundAppBar"
app:strokeColor="?attr/ColorBackgroundAppBar"
app:strokeWidth="0px"
android:elevation="@dimen/common_elevation_height_none"
android:fontFamily="@font/font_family_kaiti"
android:text="简"
android:textAlignment="center"
android:textColor="?attr/ColorTextPrimary"
android:textStyle="normal"
android:textFontWeight="700"
android:textSize="24dp" />

Am I doing sth wrong...or is MaterialButton not quite there yet? I can live with the last solution, but it increases maintenance...

Gabriele Mariotti
  • 320,139
  • 94
  • 887
  • 841
IMTanuki
  • 117
  • 1
  • 9
  • Unfortunately you can't override the background of a Material button with a drawable. You can only change the background colour using `app:backgroundTint`. Consider using a custom view or the standard app compat Button. You couldn't bundle all those properties up into a style and set that as the default style of Material button in your theme. Then you are only managing these in one place – Indiana Sep 10 '20 at 21:04
  • Which version of material components are you using and what is your app theme? – Gabriele Mariotti Sep 10 '20 at 21:30
  • @Indiana It is **not** correct. Starting with `1.2.0` you can override the background with a custom drawable. Check also:https://stackoverflow.com/a/61610556/2016562 – Gabriele Mariotti Sep 10 '20 at 21:32
  • @GabrieleMariotti, thx for the feedback. Correct me if I'm wrong, but I think the solution in the link you provided relies on setting backgroundTint to null. I did try that in the second layout above, but then my theme styles don't change (I implemented dark and light mode using 2 styles). So, while it's possible to use drawable, I think I'll stick with Indiana's solution. But...if you know a way to get around the theme stye issue, I'd sure like to hear about it! app:backgroundTint="@null" android:background = "@drawable/common_appbar_btn_background" – IMTanuki Sep 10 '20 at 23:23
  • Re theme style issue, I have 2 styles for dark light mode that I toggle. Works fine if I either: a) don't override anything in the MaterialButton background; or b) use backgroundTint. But when I use backgroundTint = "@null", then for some reason, the MaterialButton background color doesn't change when I toggle theme styles. – IMTanuki Sep 10 '20 at 23:31
  • @Indiana, thx for the suggestion. See comment above re use of styles for dark / light mode. Not sure how I could add yet another style - maybe add a sub-style to my existing styles (sorry, new to AS)? – IMTanuki Sep 10 '20 at 23:33
  • @IMTanuki create a base style with all of the shared or same properties then extend from each of these to create a .Light and .Dark style. Then in your Light theme set the light style as the default style for Material Button and the same in your apps Dark Theme. That way you will only need to declare id and text in each of your Material button components in layout XMLs – Indiana Sep 11 '20 at 06:08

1 Answers1

0

Define you app theme using Theme.MaterialComponents.DayNight:

<style name="AppTheme" parent="Theme.MaterialComponents.DayNight">
    <item name="colorPrimary">@color/colorPrimary</item>
    <item name="colorPrimaryVariant">@color/colorPrimaryLight</item>
    <item name="colorSecondary">@color/colorSecondary</item>
    <!-- ....  -->
</style>

Then, if you need, define the colors for the light and dark mode:

Example: res\values\colors.xml:

   <color name="colorPrimary">.....</color>

In res\values-night\colors.xml folders define the same color:

   <color name="colorPrimary">.....</color>

Finally define a style for your button (you don't need 2 different styles for dark and light mode):

<style name="Widget.App.Button" parent="Widget.MaterialComponents.Button">
    <item name="backgroundTint">@color/....</item>
    <item name="strokeColor">@color/....</item>
    <item name="strokeWidth">@dimen/....</item>
</style>

Last step assign the style to the Button in the layout.

<com.google.android.material.button.MaterialButton
   style="@style/Widget.App.Button"
   .../>

or globally in your app theme:

<item name="materialButtonStyle">@style/Widget.App.Button</item>

For your Button since you are not using a gradient you can use the standard attributes provided by the MaterialButton.

If you prefer to use the android:background attribute with a custom drawable you can use:

<style name="Widget.App.Button" parent="Widget.MaterialComponents.Button">
    <item name="backgroundTint">@null</item>
    <item name="android:background">@drawable/.....</item>
</style>

Then inside the drawable just use the colors or attributes defined in the app theme and in the res\values\colors.xml and res\values-night\colors.xml folders.

Gabriele Mariotti
  • 320,139
  • 94
  • 887
  • 841
  • Many thx for the very thorough answer. I think I've implemented a similar daynite option using colors-attrs-styles, and that seems to work OK. However: 1. Unless I'm missing sth, I think I do need separate styles for the button (both the color of the text and the button itself need to change). 2. I noted in my original post that, when I use backgroundTint = "@null", the drawable specs do work, but...Android doesn't seem to recognize a change in style. Could you confirm - is your approach based on the assumption that a button doesn't change when flipping from day to nite mode? Thx! – IMTanuki Sep 11 '20 at 13:48