在AlertDialog中,纠正文本颜色/外观

8

我已经困扰了相当长一段时间,一直在寻找解决方案,虽然有一些相关问题的建议,但是对我来说都没有真正起作用。所以,假设我想创建一个包含(长)消息、复选框和两个按钮的AlertDialog。

// create dialog
AlertDialog.Builder dlg = new AlertDialog.Builder(this);
dlg.setTitle(R.string.dlg_title);
dlg.setMessage(R.string.dlg_msg);

// add checkbox
final CheckBox checkbox = new CheckBox(this);
dlg.setView(checkbox);

// add buttons
dlg.setPositiveButton(...);
dlg.setNegativeButton(...);

// show dialog
dlg.show();

这个不行,因为如果对话框消息变得太长,复选框将无法完全显示。此外,在横屏模式下,它将被完全隐藏。

下一步尝试是查找原始对话框布局文件(对我来说,它位于android-sdk-linux_86/platforms/android-17/data/res/layout/alert_dialog.xml),并尝试复制相关部分以创建我们自己的“克隆”内部对话框布局,就像这样:

dialog_checkbox.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_weight="1"
    android:orientation="vertical" >

    <ScrollView
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1"
        android:overScrollMode="ifContentScrolls"
        android:paddingBottom="12dip"
        android:paddingLeft="14dip"
        android:paddingRight="10dip"
        android:paddingTop="2dip" >

        <TextView
            android:id="@+id/message"
            style="?android:attr/textAppearanceMedium"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:padding="5dip" />
    </ScrollView>

    <CheckBox
        android:id="@+id/checkbox"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

</LinearLayout>

我们可以尝试像这样将此视图添加到我们的对话框中:

// create dialog
AlertDialog.Builder dlg = new AlertDialog.Builder(this);
dlg.setTitle(R.string.dlg_title);

// add checkbox
LinearLayout checkboxLayout = (LinearLayout) View.inflate(mContext, R.layout.dialog_checkbox, null);
((TextView) checkboxLayout.findViewById(R.id.message)).setText(R.string.dlg_msg);
mCheckbox = (CheckBox) checkboxLayout.findViewById(R.id.checkbox);
mCheckbox.setText(R.string.dlg_checkbox_msg);
setView(checkboxLayout);

// add buttons
dlg.setPositiveButton(...);
dlg.setNegativeButton(...);

// show dialog
dlg.show();

这实际上运作得非常好。几乎。我们不会遇到任何问题,直到我们为应用程序使用Theme.Light。但是,一旦我们使用Theme.Light,对话框文本颜色将变为黑色,在暗色背景上无法阅读。为什么?!
  • 我们克隆了原始的Android警报对话框xml布局源代码。但是,尽管我们使用attr/textAppearanceMedium作为文本样式,但在Theme.Light下,文本颜色仍然变为黑色。
  • 如果我们使用Theme.Light并通过setMessage创建“普通”对话框,则文本颜色为白色且可读。

怎么了?如何解决这个问题?我不想以编程方式将文本颜色设置为白色或黑色,因为这在自定义用户主题上看起来不好。有什么建议吗?

4个回答

19

我曾经遇到过相同的问题,解决方法是为我的所需的对话框主题创建一个ContextThemeWrapper,并在创建AlertDialog Builder和加载要附加的视图时使用它:

ContextThemeWrapper wrapper = new ContextThemeWrapper(this, R.style.DialogBaseTheme);
AlertDialog.Builder builder = new AlertDialog.Builder(wrapper);
View view = LayoutInflater.from(wrapper).inflate(R.layout.create_warning, null); 
builder.setView(view);
<style name="DialogBaseTheme" parent="android:Theme.Dialog"/>

在 Honeycomb 及以上版本中,也已在“/values-v11/styles.xml”中定义使用 Holo 主题:

<style name="DialogBaseTheme" parent="android:Theme.Holo.Light.Dialog" />

在 Gingerbread 上,我的自定义视图(View)中的 TextView 自动变为白色,在 Honeycomb 及以上版本中,它们会自动变为黑色以适应 Holo Light 主题。


非常感谢您的回答!完美地解决了问题! - Anton Cherkashyn

1

我终于找到了解决方法。根据我的初始代码,这似乎解决了我的问题:

// add checkbox layout
LinearLayout checkboxLayout = (LinearLayout) View.inflate(new ContextThemeWrapper(context, android.R.style.Theme_Dialog), R.layout.dialog_checkbox, null);
((TextView) checkboxLayout.findViewById(R.id.message)).setText(DIALOG_TEXT);
mCheckbox = (CheckBox) checkboxLayout.findViewById(R.id.checkbox);
mCheckbox.setText(CHECKBOX_NOT_AGAIN);
setView(checkboxLayout);

请注意ContextThemeWrapper。它使得对话框主题分配给充气布局。我希望这最终能为未来解决这个问题。

不行。似乎在Android 4上无法工作...该死。有人能找到一个合适的解决方案吗? - flxapps

0

在TextView中添加一个属性:

android:textColor="@color/white"

在res/values文件夹内的colors.xml中定义白色。

<color name="white">#ffffff</color>

或者你可以直接添加

android:textColor="#fffff"(虽然不推荐。建议使用上述方法。)


正如所说,我不喜欢这个解决方案。如果有人使用自定义主题,其中对话框具有浅色背景和深色文本颜色,那么他们将会遇到问题。在我看来,这个解决方案根本不干净。 - flxapps
不要这样尝试,因为如果您显式地设置文本颜色为白色,它将覆盖任何主题的默认颜色。 - Android Killer
你不理解。一些Android用户使用自定义ROM,其中一些自定义ROM是个性化主题的。而其中一些个性化主题可能有非常亮丽的颜色。而这些亮丽的主题可能会有明亮的对话框背景。而那些具有明亮对话框背景的主题将逻辑上使用深色文本颜色来使对话框文本可读。如果我用白色覆盖这些文本颜色,就会在明亮的背景上显示白色文本。你能读懂白色背景上的白色文本吗?我不认为这样... - flxapps
在这种情况下,您可以创建一个自定义的xml文件,并将其背景设置为黑色,文本视图颜色设置为白色。它会工作得很好。 - Android Killer
那么,文本可能是可读的,但对用户来说仍然会看起来丑陋和不寻常。 - flxapps

0

您可以应用带有阴影的自定义样式,使您的文本无论文本颜色如何都可见:

<resources>
<style name="Text.Shaded.Medium" parent="@android:attr/textAppearanceMedium">
    <item name="@android:paddingLeft">4dp</item>
    <item name="@android:paddingBottom">4dp</item>
    <item name="@android:textColor">#FFFFFFFF</item>
    <item name="@android:shadowColor">#000000</item>
    <item name="@android:shadowDx">2</item>
    <item name="@android:shadowDy">2</item>
    <item name="@android:shadowRadius">2</item>
</style>
</resources>

然而,如果它对你来说不够明显,你可以应用内阴影,但不幸的是,Android没有这样的属性,所以你需要使用类似于MagicTextView(由ABentSpoon在这个问题中提到:Is there a way to add inner shadow to a TextView on Android?)的东西。


1
这个解决方案还会改变默认对话框的外观。它使对话框的外观对用户来说不可用和奇怪。我不喜欢这样的解决方案。 - flxapps

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接