Как WebView может наследовать цвета из текущей темы Android? - PullRequest
10 голосов
/ 01 февраля 2012

Этот вопрос был первоначально размещен в Google Moderator для видеовстречи AndroidDev Office Hours, которая состоялась на прошлой неделе.На вопрос был дан живой ответ, и вы можете посмотреть его здесь , если хотите.Я публикую это здесь, потому что они, кажется, заинтригованы этим, и здесь у меня есть немного больше возможностей для разработки.

A WebView обычно используется для отображения веб-контента, как задумал автор (как они утверждают втусовка).Но я использую WebView для отображения не только контента как такового, но и форматированного текста (в основном, жирный шрифт, курсив, маркированные списки и выравнивание текста).С WebView намного проще (другими словами, с HTML / CSS намного проще), чем использовать кучу TextViews и сохранять их все идеально отформатированными.

Проблема в том, что я использую этот специфическийWebView с прозрачным фоном на AlertDialog.Цвет текста WebView исходит из CSS загруженного контента, но важно, чтобы этот цвет контрастировал с цветом фона AlertDialog.И это моя проблема.

До Android 2.3 фон AlertDialog всегда был темным.Не имело значения, была ли тема приложения по умолчанию темной или светлой, AlertDialog все еще был темно-серым.Это на ванильном Android.Но даже на скинах Android (Sense, TouchWiz, MotoBlur и т. Д.) AlertDialog всегда был темным цветом (как для стандартных, так и для светлых тем).

Все это изменилось в ICS(это, вероятно, изменилось на Соте, но я не подтвердил это).Тема по умолчанию / темная теперь имеет темную AlertDialog, тогда как у светлой темы на самом деле есть светлая AlertDialog.

Поскольку я использую исключительно светлую тему в своем приложении, я легко могу решить свою проблему,загрузка содержимого WebView с различными файлами CSS.Один с темным цветом текста для версий ниже ICS и другим светлым цветом текста для ICS и выше.Это в основном решило бы мою проблему, если бы не скины OEM.

В версиях скинов для ICS они могли бы предоставить темные / светлые темы для AlertDialog.Или нет.Скорее всего, они будут делать именно то, что делали, предоставляя темные и светлые темы, как обычно, но для AlertDialog только темной версии, независимо от темы приложения.

Я мог бы включить Holoмое приложение и проблема решена таким образом, но я бы предпочел не вмешиваться в то, как система в целом выглядит на устройствах пользователя.Например, если у них есть Sense и он ему действительно нравится, я не хочу отображать Holo тематический AlertDialog при использовании моего приложения.

В конечном счете, мой вопрос таков:

Итак, как мне справиться с этим?Как сделать так, чтобы текст на моем WebView читался на фоне AlertDialog?Независимо от версии Android, используемой темы, или если она скина OEM-производителей или нет ...

Я не знаю, насколько это возможно, но одной из альтернатив для решения этой проблемы будет:каким-то образом извлеките цвет текста из темы AlertDialog в устройстве.Но не тема по умолчанию или тема Holo, а тема DeviceDefault, я верю.

Легко ли выполнить это извлечение?Может ли это быть хорошим решением моей проблемы?Есть ли у вас другие альтернативы?

Еще одна деталь ... Если вы смотрели видеовстречу и парней, которые действительно ответили мне, один из них предложил ввести CSS.Если бы я не был ясен раньше, мне не нужно этого делать.Мне просто нужно построить строку содержимого WebView с точным CSS-кодом, который я хочу, который может взять цвет текста, извлеченный из темы.

1 Ответ

3 голосов
/ 26 марта 2012

Я думаю, что для того, чтобы найти решение, мы должны быть в состоянии определить, какая тема используется во время выполнения вашими диалогами.Я предполагаю, что вы не устанавливаете тему простотыЭто означает, что будет использоваться тема диалога по умолчанию.Следующий код взят из класса Dialog и показывает, как тема по умолчанию фактически применяется к диалогу, если тема не была явно установлена.

Dialog(Context context, int theme, boolean createContextWrapper) {
    if (theme == 0) {
        TypedValue outValue = new TypedValue();
        context.getTheme().resolveAttribute(com.android.internal.R.attr.dialogTheme,
                outValue, true);
        theme = outValue.resourceId;
    }

    mContext = createContextWrapper ? new ContextThemeWrapper(context, theme) : context;
    mWindowManager = (WindowManager)context.getSystemService(Context.WINDOW_SERVICE);
    Window w = PolicyManager.makeNewWindow(mContext);
    mWindow = w;
    w.setCallback(this);
    w.setWindowManager(mWindowManager, null, null);
    w.setGravity(Gravity.CENTER);
    mUiThread = Thread.currentThread();
    mListenersHandler = new ListenersHandler(this);
    }

Теперь нам нужно выяснить, какой основной цвет текстаэтой темыМы можем сделать это следующим образом (переменная диалоговое окно является ссылкой на ваш диалог):

    TypedValue tv = new TypedValue();
    dialog.getContext().getTheme().resolveAttribute(android.R.attr.textColorPrimary, tv, true);
    int textColor = getResources().getColor(tv.resourceId);

Теперь, когда у нас есть цвет текста, нужно добавить это значение в ваше веб-представление.Я тестировал этот код на следующих устройствах

Samsung Galaxy Tab 10.1 под управлением Honeycomb

  • Theme.Holo.Light дал цвет текста чисто черный
  • Theme.Holo дал цвет текста чисто белый

HTC Sensation под управлением Gingerbread

  • Theme.Light дал цвет текста чисто белый (это правильно, так как диалог имеет темный фон
  • Theme. Черный также дал цвет текста чисто белый

Samsung Galaxy S2 под управлением Gingerbread

  • Theme. Черный дал текстовый цвет светло-серый (ffc8c8c8)
  • Theme.Light дал тот же текстовый цвет (ffc8c8c8)

Эмулятор ICS

  • Theme.Holo.Light дал цвет текста чисто черный
  • Theme.Holo дал очень светло-серый (fff3f3f3)

Так вотМетод отлично работал на всех протестированных устройствах.

Cheers Renard

...