Почему ?android:textColorPrimary получает разные значения с разными версиями API?

У меня есть виджет приложения с белым фоном. Часть отображаемого текста использует ?android:textColorPrimary, часть использует ?android:textColorSecondary, а часть использует определенные мной цвета.

Однако по какой-то причине, когда я запускаю свое приложение на версии до Nougat (24 или ниже), цвета белые, так что текст невидим на белом фоне, но все, что 24 и выше, отображается как черный или серый. Цвета, которые я определил, всегда в порядке.

Что также интересно, так это то, что код в виджете приложения почти идентичен фактическому приложению (оба отображают список элементов), а версия приложения (даже на этих старых API) использует темные цвета, но виджет по какой-то причине выбирает белые цвета для текст.

Если я проследю код XML в стилях, я доберусь до этого:

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

Что это значит? Как он узнает, какой самый заметный цвет текста? Почему виджет отличается от приложения и почему только в старых версиях API?

Могу ли я что-нибудь сделать, чтобы исправить это, чтобы оно было последовательным? Я использую ту же тему. Почему это произошло?

Примечание. Я не спрашиваю об установке определенного цвета. Конечно, я мог бы просто сделать текст черным или что-то в этом роде, но я хочу использовать эти стили, чтобы в будущем цвет мог меняться по мере необходимости, тем более что я использую тему день/ночь. Может, это связано с этим? Хорошо, я попробовал обычную тему, но проблема не устранена (текст невидим на виджете - только виджет - на более старых, чем API 24).

Пожалуйста, дайте мне знать, если что-то неясно, и я обновлю вопрос. Спасибо.


person Michael Vescovo    schedule 13.08.2017    source источник
comment
Потому что разные версии ОС используют разные темы.   -  person Phantômaxx    schedule 13.08.2017
comment
можно немного конкретнее? почему тема для виджета приложения и приложения в той же версии ОС должна отличаться? Я использую только темы appCompat. В любом случае, это должно быть что-то с темами. Конечно. просто не уверен, что.   -  person Michael Vescovo    schedule 13.08.2017
comment
Не уверен в этом. Но есть старый трюк (обходной путь!), который я позаимствовал из рабочего стола Windows: тень (смещена 1 на 1 — вниз и вправо, поэтому свет падает сверху слева, как и ожидалось). Белый текст на белом фоне все равно будет виден из-за черной (ну черноватой) тени. И тень будет практически незаметна на черном экране, останется только текст.   -  person Phantômaxx    schedule 13.08.2017
comment
Я не уверен, что вы имеете в виду. Я мог бы установить черный фон, и это сработало бы, но это не то, что мне нужно. Кажется, что использование какой-то тени не будет выглядеть так здорово. Это не очень важно, но должна быть причина (что-то, что я сделал неправильно), чтобы вызвать такое странное поведение.   -  person Michael Vescovo    schedule 13.08.2017
comment
Мой обходной путь станет понятен после того, как вы его визуализируете. Попробуйте на разных ОС. И текст всегда будет читаем. В конце концов, это всего лишь пара строк в атрибутах макета TextView.   -  person Phantômaxx    schedule 13.08.2017
comment
можете ли вы привести пример того, как это сделать?   -  person Michael Vescovo    schedule 13.08.2017
comment
android:shadowColor="@colors/black", android:shadowDx="1dp", android:shadowDy="1dp", android:shadowRadius="1". См. официальную документацию.   -  person Phantômaxx    schedule 13.08.2017
comment
хорошо, я попробовал, и это вроде сработало. Я вижу текст. но теперь у него есть тень (что неудивительно). что-то, чтобы иметь в виду в любом случае. Спасибо.   -  person Michael Vescovo    schedule 13.08.2017
comment
Просто фишка - позаимствовано из другой ОС. Все еще в силе, не так ли?   -  person Phantômaxx    schedule 17.08.2017
comment
вы можете видеть текст с ним, но он выглядит не так хорошо. Я просто установил цвет вручную, как описано в моем комментарии к принятому ответу.   -  person Michael Vescovo    schedule 18.08.2017


Ответы (2)


Что это (textColorPrimary) означает?

Это означает, что будет применено значение, указанное в android:textColorPrimary текущей темы. Итак, если вы объявили TextView в xml и применили к нему android:textColor="?android:textColorPrimary", то этот атрибут будет извлечен из темы текущего контекста, с которым этот макет раздувается.

Как он узнает, какой самый заметный цвет текста?

Это значение извлекается из темы, которую вы применили к своей активности, или из контекста, в котором представление расширяется (см. ContextThemeWrapper и android:theme). Он может отличаться от версии платформы к версии платформы. В зависимости от используемой темы она может отличаться: см. themes.xml.

Вы можете переопределить этот атрибут в своей теме:

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

Теперь вы успешно переопределили атрибут android:textColorPrimary, поэтому в дальнейшем любое представление, которое расширяется контекстом этой темы, будет видеть это переопределенное значение при ссылке на ?android:textColorPrimary.

Почему виджет отличается от приложения и почему только в старых версиях API?

Ваш виджет может быть наполнен определенной темой, в то время как приложение имеет другую тему. Если бы у них была одна и та же тема, эти атрибуты были бы одинаковыми.

person azizbekian    schedule 13.08.2017
comment
Насколько я могу судить, я использую одну и ту же тему для виджета и остальной части приложения. В противном случае наверняка было бы иначе даже на API 24 и выше. Разве это не так? Это может измениться, но, возможно, вы можете проверить мою страницу стилей здесь: github.com/mvescovo/item-reaper/blob/master/app/src/main/res/ Что-нибудь выглядит странным? - person Michael Vescovo; 13.08.2017
comment
Как и где ваш взгляд раздувается в репо? - person azizbekian; 13.08.2017
comment
Хорошо, я подумал об этом еще немного и пришел к выводу, что бессмысленно беспокоиться о том, какими будут эти цвета типа ?android:textColorPrimary (те, которые начинаются с вопросительного знака), поскольку это не похоже на это (день ночная тема) в любом случае сможет самостоятельно обновить фон виджета. Таким образом, кажется, что мне нужно обновить все это вручную, и я также могу явно установить цвет текста, используя метод, который вы объяснили. Поэтому я думаю, что это правильный ответ. Спасибо за вашу помощь! - person Michael Vescovo; 14.08.2017

Итак, ?android:textColorPrimary и ?android:textColorSecondary — это атрибуты, и они разрешаются системой. Это нормально, если они разные на разных платформах, потому что вы ссылаетесь на атрибуты Android.

Если вы хотите определить их самостоятельно, вам нужно создать свою собственную тему и поместить туда значения.

person Anton Potapov    schedule 13.08.2017
comment
Я не об этом спрашиваю. Я уже знаю это. Как они определяют эту информацию? Я склонен думать, что в моем приложении есть что-то забавное, но я не знаю, где еще искать. Я попытался просмотреть пример приложения (что-то отличное от моего приложения) и нашел это: github.com/hjanetzek/android-support-v7-appcompat/blob/master/. После внесения некоторых изменений для установки цвета текста с помощью ?android:textColorPrimary он стал белым во всех версиях. Так что это было последовательно. Моя почему-то нет. - person Michael Vescovo; 13.08.2017
comment
Я ищу идеи о том, почему это может быть непоследовательно в моем приложении и почему система выбирает светлый цвет вместо темного и наоборот. Тогда, возможно, я смогу найти проблему. - person Michael Vescovo; 13.08.2017