Skip to content

Conversation

@rasmusJenle
Copy link

@rasmusJenle rasmusJenle commented Sep 5, 2025

Problem
On Android, DetailedList currently hard-codes R.color.black for row text.
In dark mode, this makes text unreadable (black text on dark background).
Fixes #3747.

Solution
Replace the hard-coded color with theme-resolved colors:
top_text: resolved from android.R.attr.textColorPrimary
bottom_text: resolved from android.R.attr.textColorSecondary
Fallback: Color.BLACK

Screenshots with solution implemented

light_on_dark_android dark_on_light_android

As pointed out by freakboy3742 when the issue was raised, the decision whether to use textColorPrimary or textColorSecondary for bottom_text requires attention to android best practice. After looking at https://m3.material.io/components/lists/specs, I landed on textColorSecondary. top_text and bottom_text seem to work like a headline and supporting text, with varying emphases on color/contrast.

@rasmusJenle rasmusJenle marked this pull request as draft September 5, 2025 21:19
@rasmusJenle rasmusJenle marked this pull request as ready for review September 6, 2025 11:20
@rasmusJenle rasmusJenle marked this pull request as draft September 6, 2025 13:58
@rasmusJenle rasmusJenle marked this pull request as ready for review September 6, 2025 22:26
Copy link
Contributor

@johnzhou721 johnzhou721 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some unofficial suggestions. If you disagree with any of those or can't work them out, feel free to wait for a core team member.

@mhsmith mhsmith self-requested a review September 8, 2025 09:54
Comment on lines +14 to +26
def _resolve_theme_color(view, attr_id):
ctx = view.getContext()
ta = ctx.getTheme().obtainStyledAttributes([attr_id])
try:
if not ta.hasValue(0):
# CI's emulator theme always defines textColorPrimary/Secondary,
# so this path can't be exercised there.
raise RuntimeError( # pragma: no cover
f"Required theme color attribute not found: {attr_id}"
)
return ta.getColor(0, 0)
finally:
ta.recycle()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm... is there anywhere else where we might anticipate that this function gets used? If so maybe move it into libs folder? I'm not so sure though so don't do this yet.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, I suggest moving it to the base Widget class, and then it can also be used by the calls to getColor in DetailedList.create and Table.create. Note that self._native_activity is already a Context, so there's no need to require the existence of a View.

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

Successfully merging this pull request may close these issues.

DetailedList text color hard-coded to black on Android (breaks dark mode)

3 participants