Correct text color/appearance in AlertDialog

2019-04-06 23:27发布

I am struggling around with this problem for quite a long time. I searched for solutions and there were actually some suggestions for related problems, but nothing really worked correctly for me. So let's say I want to create an AlertDialog with a (long) message, a checkbox and two buttons.

// 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();

This won't work, because if the dialog message becomes too long, the checkbox will not be completely shown. Additionally, it is going to be completely hidden in landscape mode.

Next try would be to lookup the original dialog layout file (for me it is located under android-sdk-linux_86/platforms/android-17/data/res/layout/alert_dialog.xml) and attempt to copy the relevant part to create our own "clone" of the inner dialog layout, just like this:

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>

We could try to add this view to our dialog like this:

// 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();

This actually works quite well. Almost. We will not see any problem until we use Theme.Light for our app. But as soon as we use Theme.Light, the dialog text colors will become black and unreadable on the dark background. WHY?!

  • We've cloned the original Android alert dialog xml layout source code. But although we use attr/textAppearanceMedium as a text style, the text color becomes black under Theme.Light anyway.
  • If we use Theme.Light and create a "normal" dialog with a normal message via setMessage, the text color is white and readable.

What's wrong? How to solve this? I don't want to programmatically set the text color to white or black, this will not look good on custom user themes. Any suggestions?

4条回答
贼婆χ
2楼-- · 2019-04-06 23:35

Just inside textview add one attribute:

android:textColor="@color/white"

and define white color inside colors.xml which is inside res/values folder

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

Or you may add directly

android:textColor="#fffff"(though not recommended.Above method is recommended.)

查看更多
我想做一个坏孩纸
3楼-- · 2019-04-06 23:45

I THINK I finally found out how to solve it. On the basis of my initial code, this seems to solve my problem:

// 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);

Note the ContextThemeWrapper. It makes that the dialog theme is assigned to the inflated layout. I hope, this finally solves that problem for the future.

查看更多
ゆ 、 Hurt°
4楼-- · 2019-04-06 23:45

You can apply a custom style with a shadow to make your text visible whatever the text color is:

<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>

However if it isn't visible enough for you you can apply an inner shadow, but unfortunately Android doesn't have a property for that so you'll have to use something like MagicTextView (mentioned by ABentSpoon in this question: Is there a way to add inner shadow to a TextView on Android?).

查看更多
神经病院院长
5楼-- · 2019-04-06 23:52

I had the same problem and solved it by creating a ContextThemeWrapper for my desired Dialog Theme and used this when creating the AlertDialog Builder and when inflating the View to attach:

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);

The style R.style.DialogBaseTheme is defined in "/values/styles.xml" for Gingerbread and below as:

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

Then it is also defined in "/values-v11/styles.xml" for Honeycomb and upward to use the Holo theme as:

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

So on Gingerbread my custom View's TextViews are automatically coloured white and Honeycomb+ they are automatically coloured black for Holo Light.

查看更多
登录 后发表回答