1

I have an app widget with a white background. Some of the text that displays uses ?android:textColorPrimary, some uses ?android:textColorSecondary, and some use colours I've defined.

For some reason though, when I run my app on pre Nougat (24 or lower), the colours are white such that the text is invisible on the white background, but anything 24 and higher shows as black or grey. The colours I've defined are always ok.

What's also interesting is that the code in the app widget is almost identical to the actual app (both displaying a list of items) and the app version (even on these older API's) uses dark colours but the widget for some reason selects white colours for the text.

If I trace through the XML code in the styles I get to this:

    <!-- The most prominent text color.  -->
    <attr name="textColorPrimary" format="reference|color" />

What does this mean? How does it know what the most prominent text colour is? Why is it different in the widget vs the app, and why only on older API versions?

Is there anything I can do to fix this so that it's consistent? I'm using the same theme. Why would this happen?

Note: as far as just setting a specific colour, this is not what I'm asking. Sure I could just set the text to black or something but I want to use these styles so that in the future the colour can change as necessary, especially since I'm using the day/night theme. Maybe it's related to that? Ok I tried a normal theme but the problem persists (text is invisible on the widget - only the widget - on older than API 24).

Please let me know if anything is unclear and I'll update the question. Thanks.

Michael Vescovo
  • 3,741
  • 4
  • 32
  • 45
  • Because different OS versions use different themes. – Phantômaxx Aug 13 '17 at 05:50
  • can you be a bit more specific? why would the theme be different for an app widget vs an app on the same OS version? I'm using appCompat themes only. Well it's got to be something with the themes anyway. Surely. just not sure what. – Michael Vescovo Aug 13 '17 at 06:05
  • Not sure about that. But there's an old trick (workaround!) I borrowed from Windows Desktop: **shadow** (shifted 1 by 1 - down and right, so the light comes from the upper left, as expected). White text on a white background will still be visible due to a black (well, blackish) shadow. And the shadow will be nearly invisible on a black screen, leaving only the text. – Phantômaxx Aug 13 '17 at 06:12
  • I'm not sure what you mean there. I could set the background to black and it works but that's not what I'm after. Using a shadow of some sort seems like it wouldn't look so great. It's not super important but there's got to be a reason (something I've done wrong) to cause this weird behaviour. – Michael Vescovo Aug 13 '17 at 06:16
  • My workaround will become clear, after you visualize it. Try it on different OSes. And the text will always be readable. After all, it's only a couple of lines in the TextView layout attributes. – Phantômaxx Aug 13 '17 at 06:29
  • can you give me an example of how to do this? – Michael Vescovo Aug 13 '17 at 07:19
  • `android:shadowColor="@colors/black"`, `android:shadowDx="1dp"`, `android:shadowDy="1dp"`, `android:shadowRadius="1"`. See the [official docs](https://developer.android.com/reference/android/widget/TextView.html) – Phantômaxx Aug 13 '17 at 07:24
  • 1
    ok I tried it and it sort of worked. I can see the text. but now it has a shadow (unsurprisingly). something to keep in mind anyway. thanks. – Michael Vescovo Aug 13 '17 at 07:34
  • Just a trick - borrowed from another OS. Still valid, isn't it? – Phantômaxx Aug 17 '17 at 19:52
  • you can see the text with it but it doesn't look as good. I just set the colour manually as described in my comment for the accepted answer. – Michael Vescovo Aug 17 '17 at 22:24

2 Answers2

3

What does this (textColorPrimary) mean?

This means, that the value specified in the current theme's android:textColorPrimary would be applied. So, if you have declared a TextView in xml and have applied android:textColor="?android:textColorPrimary" to it, then this attribute would be fetched from the theme of the current context with which this layout is being inflated.

How does it know what the most prominent text colour is?

It is fetching that value from the theme that you have applied to your activity or from the context with which the view is being inflated (see ContextThemeWrapper and android:theme). It may differ from platform version to platform version. Depending on the theme you are using, it may differ, see themes.xml.

You can override that attribute in your theme:

<style name="AppTheme" parent="...">
    ...
    <item name="android:textColorPrimary">@color/someColor</item>
</style>

Now, you have successfully overridden android:textColorPrimary attribute, so hereafter any view that is being inflated with a context of this theme would see this overridden value when referring to ?android:textColorPrimary.

Why is it different in the widget vs the app, and why only on older API versions?

Your widget may have been inflated with a particular theme, while app has a different theme. Had they the same theme - those attributes would be same.

azizbekian
  • 60,783
  • 13
  • 169
  • 249
  • As far as I can tell I'm using the same theme for the widget and the rest of the app. Otherwise surely it would be different even on API 24 and above. Would it not? This may change but maybe you can check my styles page here: https://github.com/mvescovo/item-reaper/blob/master/app/src/main/res/values/styles.xml Anything look strange? – Michael Vescovo Aug 13 '17 at 07:29
  • How and where is your view being inflated in the repo? – azizbekian Aug 13 '17 at 10:25
  • Ok I've thought about this some more and come to the conclusion that it's pointless worrying about what these "?android:textColorPrimary" type colours will be (the ones starting with a question mark), since it doesn't look like it (the day night theme) will be able to update the widget background by itself anyway. So essentially it seems I need to update it all manually and may as well set the text colour explicitly using the method you have explained. So I think this is the correct answer. Thanks for your help! – Michael Vescovo Aug 14 '17 at 03:47
0

Well, ?android:textColorPrimary and ?android:textColorSecondary are attributes and they are resolved by system. It's ok for them to be different on different platforms because you refer to Android attributes.

If you want to define them by yourself you need to create yourown theme and put the values there.

Anton Potapov
  • 1,265
  • 8
  • 11
  • That's not what I'm asking. I already know this. How do they determine this information? I'm inclined to think there's something funny about my app but I'm not sure where else to look. I tried looking at a sample app (something different to my app) and found this one:https://github.com/hjanetzek/android-support-v7-appcompat/blob/master/res/values/styles_base_text.xml. After making some changes to set the text colour using ?android:textColorPrimary it came up as white on all versions. So it was consistent. Mine isn't for some reason. – Michael Vescovo Aug 13 '17 at 05:26
  • I'm looking for ideas as to why it might be inconsistent in my app and why the system would choose a light colour over dark colour and vice versa. Then maybe I could find the problem. – Michael Vescovo Aug 13 '17 at 05:27