4

Well as the title says, i'm using the actionBarSherlock library and a light theme, and sometimes I need to show a dialog using the alertDialog.Builder class.

Thing is, no matter what I try, the theme doesn't apply to the dialog itself. The theme should work on both new APIs and old ones (prior to honeycomb).

example:

code:

final AlertDialog.Builder builder = new AlertDialog.Builder(new ContextThemeWrapper(activity,
            R.style.AppTheme_LightDialog));

or:

final AlertDialog.Builder builder = new AlertDialog.Builder(new ContextThemeWrapper(activity,
            R.style.Theme_Sherlock_Light_Dialog));

xml:

<style name="AppTheme_LightDialog" parent="@android:style/Theme.Light">
    <item name="android:windowFrame">@null</item>
    <item name="android:windowTitleStyle">@style/DialogWindowTitle.Sherlock.Light</item>
    <item name="android:windowBackground">@drawable/abs__dialog_full_holo_light</item>
    <item name="android:windowIsFloating">true</item>
    <item name="android:windowContentOverlay">@null</item>
    <item name="android:windowAnimationStyle">@android:style/Animation.Dialog</item>
    <item name="android:windowSoftInputMode">stateUnspecified|adjustPan</item>
    <item name="android:windowActionBar">false</item>
    <item name="android:windowActionModeOverlay">true</item>
    <item name="android:windowCloseOnTouchOutside">true</item>
    <item name="android:windowNoTitle">true</item>
    <item name="android:backgroundDimAmount">0.6</item>
    <item name="android:colorBackgroundCacheHint">@null</item>
    <item name="android:textColorPrimary">@color/abs__primary_text_holo_light</item>
    <item name="android:textColorPrimaryInverse">@color/abs__primary_text_holo_dark</item>
    <item name="windowMinWidthMajor">@dimen/abs__dialog_min_width_major</item>
    <item name="windowMinWidthMinor">@dimen/abs__dialog_min_width_minor</item>
    <item name="windowActionBar">false</item>
    <item name="windowContentOverlay">@null</item>
    <item name="android:textAppearance">?android:attr/textAppearanceInverse</item>
</style>

I know i can use the dialogFragment, but is there another way? the dialogs are quite simple, and as there are many of them, it would be annoying to change them all.


EDIT: I might be wrong, but it seems that using the android:alertDialogStyle attribute (shown here) changes it for old APIs , but it doesn't have a lot of customization. In fact, it supports only colors, and I'm not sure how to set even the text color (of the title and/or the message).

android developer
  • 114,585
  • 152
  • 739
  • 1,270
  • Hmm weird. This should usually work. What does it currently look like? Can you maybe provide a screenshot? – Ahmad May 16 '13 at 16:06
  • ABS is not meant to bring dialog themes, they even removed the dialog themes in the last version. Try HoloEverywhere, i am pretty sure they support dialog themes. – stoilkov May 24 '13 at 17:19
  • @stoilkov are you sure? how come they have dialogFragment which does have the same styles (or does it?) ? why can't the same be applied to normal dialogs? are they that different? – android developer May 24 '13 at 20:49
  • Dialog-themed where removed because they don't have an action bar which is why they are not in scope for the library. You should be able to create a similar effect using the removed commit's contents. [Source](https://github.com/JakeWharton/ActionBarSherlock/commit/601bde214b56b8fad0b4fc5aaed5af0b531b6135) – Alejandro Colorado May 25 '13 at 19:47
  • I managed to make the dialog body white, but the title background is still black. Are you in the same situation? – Ilya Kogan May 26 '13 at 05:38
  • @IlyaKogan sadly i was told to let it be, and work on it later. however, since i've put a bounty, if anyone says he has succeeded it, i will try it out and if it really works, i will give it ... – android developer May 26 '13 at 07:33
  • @androiddeveloper they removed the dialog themes because they have nothing to do with the action bar. they just logically don't belong there. ABS has own versions of fragments (including dialogfragment). This is to ensure the menu-related functions work pre ICS. I am not sure if this makes much sense for dialogfragment, so my guess is it may also at some point be dropped :) – stoilkov May 26 '13 at 10:02
  • @androiddeveloper as for dialog themes - yes they are quite different. Use the proper library to support Holo themed UI elements - Holoeverywhere. In your case just use com.WazaBe.HoloEverywhere.app.AlertDialog, this should solve your problems. ABS is for the Actionbar :) – stoilkov May 26 '13 at 10:06
  • @stoilkov i've tested the HoloEverywhere sample(from the play store) and i think it should be perfect for the dialog. however, not only i can't find out how they did it in their library, but i can't even import it as they have so many errors. – android developer Jun 19 '13 at 05:24
  • @androiddeveloper HoloEverywhere works mostly with xml files. There are no errors in the project, you just have to integrate it properly. There are many tutorials, e.g. http://stackoverflow.com/questions/10608539/error-importing-holoeverywhere – stoilkov Jun 23 '13 at 16:19
  • no, it has many errors. only after adding the newest official support library to actionBarSherlock it worked. it doesn't mostly have xml files. it has a lot of code too. it's very hard to take only the interesting parts from it without taking more and more from the library. it's like a domino effect - once you take one, the others might be needed too. took me a whole day to "dissect" it – android developer Jun 23 '13 at 18:35

2 Answers2

3

After researching a bit, I think it's not an ActionBarScherlock issue, but a Light Theme issue in alert dialogs. Let's try some things:

Use:

final AlertDialog.Builder builder = new AlertDialog.Builder(new ContextThemeWrapper(activity, R.style.AppTheme_LightDialog));

Change:

<style name="AppTheme_LightDialog" parent="@android:style/Theme.Light">

To:

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

Then override the default "Theme.Dialog" styles (copy-pasted from the Android git tree):

<style name="AppTheme_LightDialog" parent="@android:style/Theme.Dialog">
    <item name="android:windowFrame">@null</item>
    <item name="android:windowTitleStyle">@android:style/DialogWindowTitle</item>
    <item name="android:windowBackground">@android:drawable/panel_background</item>
    <item name="android:windowIsFloating">true</item>
    <item name="android:windowContentOverlay">@null</item>
    <item name="android:windowAnimationStyle">@android:style/Animation.Dialog</item>
    <item name="android:windowSoftInputMode">stateUnspecified|adjustPan</item>
</style>

You may need to copy the original resources (@android:style/DialogWindowTitle, @android:style/Animation.Dialog and @android:drawable/panel_background) to your project.

And finally, the tricky part (from Shawn Castrianni ), as it seems Android needs some extra help to apply correctly a style to AlertDialog's text. Add to your "AppTheme_LightDialog" style:

<item name="android:textColor">?android:attr/textColorPrimaryInverseDisableOnly</item>

UPDATE:

It seems that prior to Honeycomb text styling is not actually applied to AlertDialogs. The above code gives you a solution to >=Honeycomb devices. There's an interesting work-around to make it work also in those devices (check this and this), but you may want to start asking you if you prefer a different approach which requires less work.

BTW, I'm not sure if it's your case, but it's important that you also use the same ContextThemeWrapper if you inflate a custom layout for the AlertDialog. For example,

Change:

View view = View.inflate(activity, R.layout.myDialog, null);

To:

View view = View.inflate(new ContextThemeWrapper(activity, R.style.AppTheme_LightDialog), R.layout.myDialog, null);
Community
  • 1
  • 1
Alejandro Colorado
  • 6,034
  • 2
  • 28
  • 39
  • didn't work, plus for some reason, after trying to update the actionBarSherlock library, i can't use the values i've used for android:windowTitleStyle and android:windowBackground as i've used before. – android developer May 16 '13 at 22:41
  • Probably because with the new versions, dialog-themed activities where removed because they don't have an action bar which is why they are not in scope for the library. You should be able to create a similar effect using the removed commit's contents. [Source](https://github.com/JakeWharton/ActionBarSherlock/commit/601bde214b56b8fad0b4fc5aaed5af0b531b6135) – Alejandro Colorado May 25 '13 at 19:53
  • i get that i need to download the images files, but do i need to copy the red marked lines too? or just a part of them? also, can i set the dialog theme to dialogs instead of activities? – android developer May 25 '13 at 20:19
  • I edited my answer. I would try it before dedicating a big effort to revert ActionBarSherlock's removed contents. – Alejandro Colorado May 25 '13 at 23:18
  • your xml shows an error on eclipse for the android:windowTitleStyle and android:windowBackground lines, as their values are not public. – android developer Jun 17 '13 at 08:46
  • You can easily fix it copying the original resources (`@android:style/DialogWindowTitle`, `@android:style/Animation.Dialog` and `@android:drawable/panel_background`) to your project. – Alejandro Colorado Jun 17 '13 at 21:28
  • i now got panel_background from http://code.google.com/p/bankdroid/source/browse/trunk/bankdroid.soda/res/drawable/panel_background.xml?r=222 , the style is available on android-sdk\platforms\android-16\data\res\values\styles.xml . the Animation.Dialog wasn't needed. after all of this, it still doesn't do anything to android 2.3 devices (specifically galaxy s2 and galaxy mini, which have their own customized themed dialogs). – android developer Jun 18 '13 at 07:01
  • so it's not available for pre-honeycomb, and i need to use custom solutions? too bad. i've even tried holoeverywhere library, and even though it works (in their sample app), it has tons of files and i'm not sure how to use it and if it's possible to only get the part of the dialogs from there. – android developer Jun 19 '13 at 22:17
  • As I say, there's a work-around to make it work. Check them as there's not too much code to change. – Alejandro Colorado Jun 19 '13 at 22:19
  • i see. can you please show a link about it not being available for pre-honeycomb versions? – android developer Jun 19 '13 at 22:20
  • [Here](http://stackoverflow.com/a/2490122/1587345), [here](http://blog.stylingandroid.com/archives/280) and [here](http://stackoverflow.com/questions/2422562/how-to-change-theme-for-alertdialog/5392617#5392617). – Alejandro Colorado Jun 19 '13 at 22:22
  • this is very weird that they didn't think about it. can you think of a way to get only what is needed from the holoeverywhere library? only dialogs... ? – android developer Jun 19 '13 at 22:28
  • Sorry, I've never used it. You could try the solutions I posted or import the whole library and use only the Dialogs (some examples: [here](http://stackoverflow.com/questions/12481164/whats-a-correct-way-of-using-holoeverywhere?rq=1) and [here](http://stackoverflow.com/questions/15774201/holoeverywhere-dark-action-bars-and-dialogs) – Alejandro Colorado Jun 19 '13 at 22:33
  • isn't the answer you've written (with the ContextThemeWrapper) the same as the CTOR method i've used? did it work for you? – android developer Jun 19 '13 at 22:37
  • I mean the links in my updated answer ([this](http://stackoverflow.com/questions/2422562/how-to-change-theme-for-alertdialog/5392617#5392617) and [this](http://blog.stylingandroid.com/archives/280)). They create a custom Builder which inflates two layouts (one for the title and another one for the body of the message). It should work on pre-Honeycomb devices. – Alejandro Colorado Jun 19 '13 at 22:42
  • why shouldn't it also work with the default alertDialog builder? it uses simple views and layouts too, no? – android developer Jun 19 '13 at 22:47
  • Maybe because of [this](http://stackoverflow.com/questions/2422562/how-to-change-theme-for-alertdialog/2490122#2490122) – Alejandro Colorado Jun 19 '13 at 22:53
  • because they call a CTOR of the alertDialog that has a theme? indeed. this is quite problematic to fix. i guess then that i should use a customized alert or the holoeverywhere library... – android developer Jun 20 '13 at 05:28
  • is it possible perhaps to extend the alertDialog.Builder, and make some tricks to it in case it's a low API ? – android developer Jun 20 '13 at 08:44
  • That's exactly what the links I gave do (for example, [this one](http://blog.stylingandroid.com/archives/280)). – Alejandro Colorado Jun 20 '13 at 09:35
  • no, it's not. it doesn't use the default layout of the builder, and it actually doesn't implement all of the methods. it extends from it, but the usage of such a class won't work if you use methods from both classes (for example setNegativeButton) . it's very partial and what i wish is to use what is available, yet set a theme to it (the holo-light theme in my case). – android developer Jun 20 '13 at 09:47
  • in the end, i've created a totally new dialog, but it's based on the official resources of android for the dialog. – android developer Jun 20 '13 at 14:17
1

This is what I did and it made the body of the dialog white. The title is still on a black background:

new AlertDialog.Builder(
    new ContextThemeWrapper(
        activity,
        R.style.Theme_Sherlock_Light));

I also tried Theme_Sherlock_Light_NoActionBar, but it doesn't seem to make any difference.

Ilya Kogan
  • 21,995
  • 15
  • 85
  • 141