Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Problem with background and text color of buttons #523

Closed
OneManStudioDotSe opened this issue Sep 10, 2018 · 11 comments
Closed

Problem with background and text color of buttons #523

OneManStudioDotSe opened this issue Sep 10, 2018 · 11 comments

Comments

@OneManStudioDotSe
Copy link

OneManStudioDotSe commented Sep 10, 2018

Hello and thanks for this very nice library.

I have a strange problem that I could definitely use some help to sort things out.

I am showing a date and time picker which I am theming a bit. My problem is that the 'ok' and 'Cancel' buttons seem to get as both background color and text color the accent color of my theme.

Here are 2 screenshots and the related code:

screen shot 2018-09-10 at 18 52 22

  private void startDatePicker() {
        Calendar now = Calendar.getInstance();
        DatePickerDialog dpd = DatePickerDialog.newInstance(
                this,
                now.get(Calendar.YEAR), // Initial year selection
                now.get(Calendar.MONTH), // Initial month selection
                now.get(Calendar.DAY_OF_MONTH) // Initial day selection
        );

        dpd.dismissOnPause(true);
        dpd.setLocale(Locale.getDefault());
        dpd.setOkText("Nice!");
        dpd.setAccentColor(0xFF46A4C3);
        dpd.setTitle("Which day will it happen?");
        dpd.setThemeDark(false);
        dpd.setVersion(DatePickerDialog.Version.VERSION_2);
        dpd.show(getActivity().getFragmentManager(), "TAG_FOR_DATE_PICKER");
    }

And the time picker:
screen shot 2018-09-10 at 18 52 34

private void startTimePicker() {
        Calendar now = Calendar.getInstance();
        TimePickerDialog tpd = TimePickerDialog.newInstance(
                this,
                now.get(Calendar.HOUR_OF_DAY),
                now.get(Calendar.MINUTE),
                true);

        tpd.dismissOnPause(true);
        tpd.setLocale(Locale.getDefault());
        tpd.setOkText("Nice!");
        tpd.setTitle("Any specific time?");
        tpd.setThemeDark(false);
        tpd.setAccentColor(ContextCompat.getColor(getActivity(), R.color.white));
        tpd.setOkColor(ContextCompat.getColor(getActivity(), R.color.temp_color_2));
        tpd.setVersion(TimePickerDialog.Version.VERSION_2);
        tpd.show(getActivity().getFragmentManager(), "TAG_FOR_TIME_PICKER");
    }

Here is my theme:

<style name="AppTheme" parent="BaseTheme">
        <item name="windowActionBar">false</item>
        <item name="windowNoTitle">true</item>
        <item name="windowActionBarOverlay">false</item><!-- new -->
        <item name="android:windowBackground">@color/white_alabaster</item><!-- new -->
    </style>

<style name="BaseTheme" parent="Theme.MaterialComponents.Light.NoActionBar">
        <item name="colorPrimary">@color/blue_picton</item>
        <item name="colorPrimaryDark">@color/blue_cerulean</item>
        <item name="colorAccent">@color/pink_hot</item>
    </style>

And the colors.xml:

 <color name="colorAccent">@color/pink_hot</color>
    <!-- theme colors -->
    <color name="pink_hot">#ff62cb</color>
    <color name="pink_lavender">#fcaae1</color>
    <color name="pink_persian">#f37ecc</color>

I have removed any other library that might have been colliding with the attributes of your library.

So, my question is if you know what is causing this problem or if I can set both the background color and text color of the buttons.

Thanks :)

@OneManStudioDotSe
Copy link
Author

Also, for some very strange reason, I cannot set the color of the text at either the 'ok' or 'cancel' button to be white. Not with Color.parse("#FFFFFF), not with Color.parse("white"), not with a color from colors.xml. No damn way to do that!

Could there be a collision with some other library or id of color?
Some other idea that comes to mind regarding this. It is fine if the buttons are getting the color of the accent color but I would like the text to be white to make the contrast better.

@wdullaer
Copy link
Owner

This looks like a strange one.
I'm going to assume you're running the latest version.

If you're running api-version >= 21, the background of the buttons is set with ?android:colorButtonNormal (or at least that's the only place it's using a platform resource)
So either you are overwriting this attribute somewhere in your app, or there is a framework customization in place.
Are you having this issue in the emulator as well?

@OneManStudioDotSe
Copy link
Author

OneManStudioDotSe commented Sep 11, 2018

Here is my project's setup:

compileSdkVersion 28
buildToolsVersion '28.0.2'
minSdkVersion 16
targetSdkVersion 28

Also, I am using version 3.6.3 of the library, AndroidX (v. 1.0.0-rc02) and Material Components (v. 1.0.0-rc02).

The previous screenshots were from the emulator. On my phone (Google Nexus 5X with Android 8.0) I get the same result.

No matter if I set the color of the ok button with

dpd.setOkColor(ContextCompat.getColor(getActivity(), R.color.white));

or

tpd.setOkColor(Color.parseColor("#ffffff"));

it is always not visible. I can see though that when it is pressed, the color of the text is pink (the accent color).

There is no direct or indirect assignment of the android:colorButtonNormal anywhere in my code. I have removed questionable libraries to remove the risk of them fiddling around but still no result :(

Any suggestions what else to try or look at?

@OneManStudioDotSe
Copy link
Author

Answering my own questions, the problem was caused from the use of Theme.MaterialComponents.Light.NoActionBar.

It was fixed when I reverted to the use of Theme.MaterialComponents.Light.NoActionBar.Bridge which uses the new Material Components a bit more careful when playing with previous app compat elements.

In a nutshell, for future generations, use 'Theme.MaterialComponents.Light.NoActionBar.Bridge' as your theme when using this library.

@wdullaer Feel free to close this issue.

@wdullaer
Copy link
Owner

So it was related to a library overwriting some values. Thanks for looking into this some more!
Issue #524 is similar but worse: it leads to an exception when changing the theme.
I will try to phase out the usage of these framework attributes to avoid these kind of issues.

I will track that progress in #524 and close this one.

@yanniks
Copy link

yanniks commented Sep 22, 2018

I would not say that this problem is resolved.
When using Theme.MaterialComponents.Light.NoActionBar, I'm still running into the background color issue and I would prefer sticking to the default themes instead of compatibility ones.

Also, it seems like the bridge themes match the "old" Material design guidelines while Theme.MaterialComponents.Light.NoActionBar uses the new ones. A good example is the Snackbar which looks different depending on which theme you're using.

@DennyWeinberg
Copy link

+1! The button text color and the button background color are both using the accent color. So we can't see the button text.

@wdullaer
Copy link
Owner

wdullaer commented Oct 8, 2018

So this really is not my problem.
If you take a look here https://github.com/material-components/material-components-android/blob/master/docs/getting-started.md#material-components-themes, you can see that the material-components library is using a custom layout inflater which replaces Button with instances MaterialButton. From the perspective of my library that is the client application rewriting the code on the fly, I can't possibly be expected to support any random code transformation.
This is also why that library provides the bridge themes which are much less invasive (and why their docs mention mention at least ten times that you should double check everything after changing the theme because weird stuff might occur).

As an additional workaround you can also add the following line to your own application theme

<item name="viewInflaterClass">androidx.appcompat.app.AppCompatViewInflater</item>

This will disable the custom LayoutInflater (it's only used to replace buttons according to the docs). You should probably replace all instances of Button in your app with MaterialButton (in my book it's always better to be explicit about the things you want rather than rely on some magic pixie dust behind the scenes)

Other than depending on this library, there are no other fixes for this that I can see.
I specifically vendored the material button at the time to avoid having a garbled design each time the dependency changes.

wdullaer added a commit that referenced this issue Oct 9, 2018
@ezet
Copy link

ezet commented Nov 4, 2018

Another workaround is to overwrite the button layout.
Copy https://github.com/wdullaer/MaterialDateTimePicker/blob/master/library/src/main/res/layout/mdtp_done_button.xml, replace Button with com.google.android.material.button.MaterialButton and replace the style with style="@style/Widget.MaterialComponents.Button.TextButton".

In fact, it would be enough to just set the style, as the Button is being replaced with MaterialButton regardless, which causes the issue in the first place.

This will apply the new default text button style to the buttons.

@TurKurT656
Copy link

@ezet yes i think this is better than replacing the whole LayoutInflater.

@ubuntudroid
Copy link

So to sum up for everyone reading this. As @ezet mentions the fix is to simply add this line to your styles.xml:

<style name="mdtp_ActionButton.Text" parent="Widget.MaterialComponents.Button.TextButton.Dialog"/>

No need for a the Bridge theme then. :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

7 participants