【问题标题】:How can a WebView inherit colors from the current Android theme?WebView 如何从当前的 Android 主题继承颜色?
【发布时间】:2012-02-23 17:27:12
【问题描述】:

这个问题最初是在上周举行的 AndroidDev Office Hours Hangout 的 Google 汇问上发布的。这个问题实际上是现场回答的,如果你愿意,你可以观看here。我在这里发布它是因为他们似乎对此很感兴趣,在这里我有更多的空间来详细说明。

WebView 通常用于按作者的意图显示 Web 内容(正如他们在环聊中所说的那样)。但我使用WebView 来显示内容,而不是内容本身,而是格式化文本(主要是粗体、斜体、项目符号列表和文本对齐方式)。使用WebView(换句话说,使用 HTML/CSS 更容易)比使用一堆 TextView 并保持其完美格式要容易得多。

问题是我在AlertDialog 上使用具有透明背景的特定WebViewWebView 文本颜色来自加载的内容 CSS,但重要的是此颜色与 AlertDialog 的背景颜色形成对比。这就是我的问题。

在 Android 2.3 之前,AlertDialog 背景始终是深色的。无论应用程序主题是默认的深色还是浅色,AlertDialog 仍然是深灰色。这在香草 Android 上。但即使在带有皮肤的 Android(Sense、TouchWiz、MotoBlur 等)上,AlertDialog 始终是深色(对于默认/深色和浅色主题)。

这一切都随着 ICS 发生了变化(它可能在 Honeycomb 上发生了变化,但我没有确认)。默认/深色主题现在有一个深色AlertDialog,而浅色主题实际上有一个浅色AlertDialog

由于我在我的应用程序中专门使用浅色主题,我可以通过使用不同的 CSS 文件加载 WebView 内容来轻松解决我的问题。一种对于 ICS 以下的版本具有深色文本颜色,对于 ICS 及以上版本具有另一种浅色文本颜色。如果不是 OEM 皮肤,这将主要解决我的问题。

在他们的 ICS 皮肤版本中,他们可能会为 AlertDialog 提供深色/浅色主题。或不。他们更有可能做他们一直在做的事情,像往常一样提供深色和浅色主题,但对于AlertDialog,只有深色版本,无论应用程序的主题是什么。

我可以在我的应用程序上强制Holo 并以这种方式解决问题,但我不希望干扰整个系统在用户设备上的外观。例如,如果他们有 Sense 并且真的很喜欢它,我不想在使用我的应用程序时显示 Holo 主题 AlertDialog

最后,我的问题是:

那么,我该如何应对呢?如何确保WebView 上的文本在AlertDialog 背景下是可读的?无论 Android 版本、所使用的主题或是否由 OEM 皮肤...

我不知道这有多可行,但解决此问题的一种替代方法是,以某种方式从设备中的 AlertDialog 主题中提取文本颜色。但不是默认主题或Holo 主题,而是我相信的DeviceDefault 主题。

这种提取容易吗?它可以很好地解决我的问题吗?您还有其他选择吗?

最后一个细节...如果您观看了视频群聊,并且对于那些真正回答我的人来说,其中一个人建议注入 CSS。如果我之前不清楚,我不需要这样做。我只需要使用我想要的确切 CSS 构建 WebView 内容字符串,它可以采用从主题中提取的文本颜色。

【问题讨论】:

  • 这并不是问题的真正答案(我真的没有给你一个好的答案),但从 Android 4.0 开始,Holo 主题保证不会跨设备更改,所以您将能够在 CSS 中对颜色进行硬编码,而不必担心背景发生变化。
  • @RomanNurik 是的,我知道。但就像我说的那样,我真的不想在我的应用程序上强制使用特定的样式(即使它只是在 AlertDialog 上)。我的意思是,由于 OEM 的定制,有很多人购买特定的手机,我不想弄乱他们的选择。但我可能会为 Android 3.x 使用 AlertDialog.THEME_HOLO_DARKAlertDialog.THEME_DEVICE_DEFAULT_DARK 对于 Android 4.x。这似乎是我更好的选择......
  • 另一种选择是您可以动态查询某些属性并在运行时注入 CSS..
  • 是的,但这需要更多的工作。现在我只会做我在之前评论中描述的事情。这不是完美的解决方案,但这是我可以接受的。如果我的用户曾经抱怨过 AlertDialog 样式,我会再次担心这个问题。感谢您对@RomanNurik 的支持。

标签: android colors android-webview android-alertdialog android-theme


【解决方案1】:

我认为,为了找到解决方案,我们必须能够确定您的对话框在运行时使用的主题。我假设您没有明确设置主题。这意味着将使用默认对话框主题。以下代码来自 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);
    }

现在我们需要找出该主题的主要文本颜色是什么。我们可以这样做(变量 dialog 是对您的对话框的引用):

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

现在我们有了文本颜色,只需将该值注入您的 webview 即可。 我用以下设备测试了这段代码

运行 Honeycomb 的三星 Galaxy Tab 10.1

  • Theme.Holo.Light 将文本颜色设为纯黑色
  • Theme.Holo 赋予文本颜色纯白色

HTC Sensation 运行 Gingerbread

  • Theme.Light 给出了纯白色的文本颜色(这是正确的,因为 对话框有深色背景
  • Theme.Black 也赋予了纯白色的文本颜色

运行 Gingerbread 的三星 Galaxy S2

  • Theme.Black 将文本颜色设为浅灰色 (ffc8c8c8)
  • Theme.Light 给出了相同的文本颜色 (ffc8c8c8)

ICS 模拟器

  • Theme.Holo.Light 将文本颜色设为纯黑色
  • Theme.Holo 给出了非常浅的灰色 (fff3f3f3)

所以这种方法在所有测试设备上都运行良好。

干杯 雷纳德

【讨论】:

  • 哇,这正是我一直在寻找的东西。不幸的是,我没有时间自己测试它,看看它是否真的解决了我的问题(我想它确实如此)。但是你可以在模拟器上测试 ICS,是吗?
  • Sure.Tests 在模拟器上也是积极的。
猜你喜欢
  • 1970-01-01
  • 2021-06-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-01-13
  • 2021-08-06
  • 2016-05-16
  • 1970-01-01
相关资源
最近更新 更多