Android Dialog theme makes icon too light

ilomambo picture ilomambo · Feb 16, 2013 · Viewed 11.7k times · Source

I created a new application in Eclipse, targeted to Jelly Bean. This is all automatically created code. The manifest sets the application theme to AppName:

<application
    android:allowBackup="true"
    android:icon="@drawable/ic_launcher"
    android:label="@string/app_name"
    android:theme="@style/AppTheme" >
    . . . 

which translates to AppBaseTheme for styles in the values dir:

<resources xmlns:android="http://schemas.android.com/apk/res/android">

    <!--
        Base application theme, dependent on API level. This theme is replaced
        by AppBaseTheme from res/values-vXX/styles.xml on newer devices.
    -->
    <style name="AppBaseTheme" parent="android:Theme.Light">
        <!--
            Theme customizations available in newer API levels can go in
            res/values-vXX/styles.xml, while customizations related to
            backward-compatibility can go here.
        -->
    </style>

    <!-- Application theme. -->
    <style name="AppTheme" parent="AppBaseTheme">
        <!-- All customizations that are NOT specific to a particular API-level can go here. -->
    </style>

</resources>

And values-v14/styles.xml is:

<resources>

    <!--
        Base application theme for API 14+. This theme completely replaces
        AppBaseTheme from BOTH res/values/styles.xml and
        res/values-v11/styles.xml on API 14+ devices.
    -->
    <style name="AppBaseTheme" parent="android:Theme.Holo.Light.DarkActionBar">
        <!-- API 14 theme customizations can go here. -->
    </style>

</resources>

I then created a confirmation dialog box before quiting:

    case R.id.menu_quit:
        new AlertDialog.Builder(this)
        .setIcon(android.R.drawable.ic_dialog_alert)
        .setTitle(R.string.confirm_title)
        .setMessage(R.string.confirm_text)
        .setPositiveButton(R.string.ok, new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                finish();    
            }

And the resulting dialog box is:

resulting dialog box

Why is the ic_dialog_icon so light? It is barely visible. I am using all defaults, I did not modify the theme or any colors, Shouldn't the system pick an icon wiht more contrast to its background? How can I fix it?

Edit with fix
Following Tomik info I read the documentation for android.R.attr.alertDialogIcon and made this fix ( replaced setIcon() with setIconAttribute() )

        new AlertDialog.Builder(this)
        .setIconAttribute(android.R.attr.alertDialogIcon)
        .setTitle(R.string.confirm_title)
        .setMessage(R.string.confirm_text)
        .setPositiveButton(R.string.ok, new DialogInterface.OnClickListener() {

Now the dialog looks like this:

enter image description here

Answer

Tomik picture Tomik · Feb 16, 2013

The problem is that you are using private resource android.R.drawable.ic_dialog_alert.

Using private resources is problematic, they can vary on different devices and you can't even be sure that they are present on all devices. The best is to avoid using private resources. If you need them, you should copy them from Android sources and put them in your project's resources.

The exact reason why your resource is too white is that you are using resource (android.R.drawable.ic_dialog_alert) that is used for standard (non-Holo) theme.
But for devices running Android 4.x (API level 14) you are using Holo theme (android:Theme.Holo.Light.DarkActionBar) which is normally using different resource.

With Holo theme the default alert icon is android.R.id.ic_dialog_alert_holo_dark for the dark theme or android.R.id.ic_dialog_alert_holo_light for the light theme (your case, you should use this resource instead).

Note: Since API level 11 there is an attribute android.R.attr.alertDialogIcon which refers to the default alert dialog icon for the current theme. In your code you can use it this way:

case R.id.menu_quit:
    new AlertDialog.Builder(this)
    .setIconAttribute(android.R.attr.alertDialogIcon)
    .setTitle(R.string.confirm_title)
    .setMessage(R.string.confirm_text)
    .setPositiveButton(R.string.ok, new DialogInterface.OnClickListener() {
        @Override
        public void onClick(DialogInterface dialog, int which) {
            finish();    
        }

Still I recommend to copy the resource from Android sources to your project's resources because that's the only way you can be sure that the icon will always look the same.