Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android: Issue with showing dialog from Theme.Light activity

Tags:

android

I am trying To show a dialog from a PreferenceActivity, which is set to Theme.Light. The dialog shows with dark text on a dark background:

enter image description here

I assume it uses dark text because it is inheriting the text color from the parent activity, or something similar. I would like the dialog to either use white text on the dark background, or use a white background with dark text, as the PreferenceActivity does when set to Theme.Light.

This seems to be a known problem, the workarounds I have found involve creating and using a custom style that extends Theme.Dialog and using it to instantiate the dialog. Something like:

<style name="CustomDialog" parent="@android:style/Theme.Dialog">
<item name="android:textColor">?android:attr/textColorPrimaryInverseDisableOnly</item>
</style>

Dialog dialog = new Dialog(context, R.style.CustomDialog);

I tried this, but it made no difference. I also tried a number of different values for textColor, none of which modified the Dialog's text color. As a sanity check, I added:

     <item name="android:background">#FFFF0000</item>

to the style, which resulted in a dialog with a red background (so I am sure that I am instantiating the dialog properly).

The closest I have come to a solution is just setting the dialog's background color to white, which gives the below dialog. But this is not a good solution, because some version or some device might not use the same behavior I am seeing when inverting text color:

enter image description here

So, is there a good way to set text color on a dialog displayed from a Theme.Light activity?

like image 488
ab11 Avatar asked Oct 14 '11 17:10

ab11


1 Answers

I assume that you use AlertDialog.Builder and set the list using one of the setSingleChoiceItems methods which doesn't use your own ListAdapter. Instead it creates its own instead with the wrong style. To fix this, you should call setSingleChoiceItems(ListAdapter adapter, int checkedItem, DialogInterface.OnClickListener listener) and provide such an adapter which would use a layout with the needed style.

Now, why this happens. The actual adapter creation happens in the file com.android.internal.app.AlertController, where the following line selects the layout for single choice lists:

int layout = mIsSingleChoice 
                    ? R.layout.select_dialog_singlechoice : R.layout.select_dialog_item;

Here is the aforementioned layout:

<CheckedTextView xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@android:id/text1"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:minHeight="?android:attr/listPreferredItemHeight"
    android:textAppearance="?android:attr/textAppearanceLarge"
    android:textColor="@android:color/primary_text_light_disable_only"
    android:gravity="center_vertical"
    android:paddingLeft="12dip"
    android:paddingRight="7dip"
    android:checkMark="@android:drawable/btn_radio"
    android:ellipsize="marquee"
/>

As you can see, the line which sets the text color contains not a reference to a theme, but a hardwired color. That's why when this thing gets inflated during the list creation, it will always use the same color, regardless of what style you want it to use. So the right action to overcome this problem is to use your own layout and your own ListAdapter.

like image 180
Malcolm Avatar answered Oct 20 '22 15:10

Malcolm