Theme not applying to DialogFragment on Android

38,508

Solution 1

I believe you need to set the theme on the actual Dialog and not the Fragment

Use this constructor to create your AlertDialog:

 AlertDialog.Builder(Context context, int theme)

ie

 AlertDialog.Builder builder = new AlertDialog.Builder(getActivity(), theme)

Solution 2

You shoudn't use the AlertDialog.Builder(Context, int) constructor with the support library because it is only available since API 11.

To setup a theme to your dialog, use instead a ContextThemeWrapper like this:

ContextThemeWrapper context = new ContextThemeWrapper(getActivity(), android.R.style.Theme_Holo_Dialog_NoActionBar);
AlertDialog.Builder builder = new AlertDialog.Builder(context);

Solution 3

I just lost a lot of time to this, but I finally found a way to do this entirely in xml.

In an application theme, Dialogs are actually themed separately. So to style all DialogFragments with green buttons and green EditText hints, you would make a style like this:

<style name="DialogTheme" parent="@android:style/Theme.Holo.Light.Dialog">
    <item name="android:buttonStyle">@style/button_green</item>
    <item name="android:textColorHint">@color/green</item>
</style>

Then add this theme to your application theme as the dialogTheme

<style name="MyTheme" parent="android:Theme.Holo.Light">
    <item name="android:dialogTheme">@style/DialogTheme</item>
</style>

Many thanks to whoever wrote this post for showing me the path to what I'd been searching for!

Solution 4

Here is a more current answer, using target SDK of 23 and min SDK of 14, this code works perfectly for me.

The main change from the code in the question is setting the theme in the constructor, only overriding onCreateDialog(), and using the AlertDialog class from the v7 support library.

Using this code, the green text flat (borderless) buttons are shown on 4.4.4 as opposed to the default gray buttons with borders.

import android.support.v7.app.AlertDialog;
import android.app.Dialog;
import android.support.v4.app.DialogFragment;
import android.content.DialogInterface;
import android.os.Bundle;

public class MyDialog extends DialogFragment {

    String message;

    public MyDialog(String m) {
        message = m;
        int style = DialogFragment.STYLE_NORMAL, theme = 0;
        theme = android.R.style.Theme_Holo_Dialog_NoActionBar;
        setStyle(style, theme);
    }

    @Override
    public Dialog onCreateDialog(Bundle savedInstanceState) {

        return new AlertDialog.Builder(getActivity())
                .setMessage(message)
                .setPositiveButton("OK",
                    new DialogInterface.OnClickListener() {
                        public void onClick(DialogInterface dialog, int whichButton) {
                            ((EnterPhoneNumberActivity)getActivity()).doPositiveClick();
                        }
                    }
                )
                .setNegativeButton("EDIT",
                    new DialogInterface.OnClickListener() {
                        public void onClick(DialogInterface dialog, int whichButton) {
                            ((EnterPhoneNumberActivity)getActivity()).doNegativeClick();
                        }
                    }
                )
                .create();
    }
}

Usage in an AppCompatActivity:

    String message = "test";
    if (message != null) {
        DialogFragment newFragment = new MyDialog(message);
        newFragment.show(getSupportFragmentManager(), "dialog");
    }
Share:
38,508

Related videos on Youtube

luthier
Author by

luthier

I'm #SOreadytohelp :)

Updated on July 09, 2022

Comments

  • luthier
    luthier almost 2 years

    I'm switching my old Dialogs to DialogFragment, but the themes and styles don't seem to be working.

    I'm using the DialogFragment from the compatibility library v4, and in the onCreate method I've tried calling setStyle(style, theme); with a lot of different themes, but the dialog always shows as an "old" dialog in the emulator running Android 4.0.3 (i.e., it does not shows in Holo theme).

    Is there anything else that I should be doing? Does using the compatibility library disables the Holo theme or anything? If this is the case, should I create two DialogFragments, one for older versions and one for newer versions?

    Thanks!


    Here's the (simplified) code for my dialog. I've tried both Theme_Holo_Dialog_NoActionBar and Theme_DeviceDefault_Dialog_NoActionBar, but the Android 4 emulator always shows the dialog as an "old" dialog instead of using the Holo theme. What am I doing wrong? :(

    [...]
    import android.support.v4.app.DialogFragment;
    [...]
    
    public class AlertDialogFragment extends DialogFragment {
    
      public static AlertDialogFragment newInstance(int id) {
    
        AlertDialogFragment f = new AlertDialogFragment();
        Bundle args = new Bundle();
        args.putInt("id", id);
        f.setArguments(args);
    
     }
    
      @Override
      public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        int style = DialogFragment.STYLE_NORMAL, theme = 0;
        theme = android.R.style.Theme_Holo_Dialog_NoActionBar;
        setStyle(style, theme);     
      }
    
      @Override
      public Dialog onCreateDialog(Bundle savedInstanceState) {
    
        mId = getArguments().getInt("id");
        AlertDialog.Builder builder = new AlertDialog.Builder(getActivity())
            .setTitle(mTitle)
            .setMessage(mMessage)
            .setPositiveButton(getString(R.string.btn_ok), new DialogInterface.OnClickListener() {      
                @Override
                public void onClick(DialogInterface dialog, int which) {
                    dismiss();                  
                }
            });
            return builder.create();
        }
    
    • Blundell
      Blundell almost 12 years
      What style are you inheriting from, show us styles.xml also what is your targetSdk? it needs to be over 11
    • luthier
      luthier almost 12 years
      I'm targeting SDK 14, and I'm not even using a styles.xml file, I'm just calling setStyle(style, theme); in the onCreate method of the DialogFragment trying multiple combinations of style and theme. For example, in my "old" dialog I used android.R.style.Theme_DeviceDefault_Dialog_NoActionBar and it showed as Holo in the ICS emulator, but now using the same theme it doesn't.
    • Blundell
      Blundell almost 12 years
      Try implicitly using Holo: android.R.style.Theme_Holo_Dialog
    • luthier
      luthier almost 12 years
      Thanks, I tried it too... didn't work :(
    • Blundell
      Blundell almost 12 years
      You'll have to edit your post, put a code example of what you have tried, your more likely to get some answers that way
    • luthier
      luthier almost 12 years
      Thanks for the comment Blundell, I posted the code above.
    • Blundell
      Blundell almost 12 years
      So I thought the docs said don't override onCreate AND onCreateDialog because you get weird behaviour. Also I can't see where you are actually setting the theme anywhere
    • luthier
      luthier almost 12 years
      I'm sorry, I somehow deleted the setStyle call when I pasted the code. But it was there, I promise :) [and it's there now] On the other hand, the only thing that I saw in the docs was that there's no need for onCreateView if you are using onCreateDialog, but nothing about onCreate. If this is the case, could you please tell me where you saw it? Thanks!
    • Blundell
      Blundell almost 12 years
      Yeah your right I got onCreate and onCreateView mixed up
    • Admin
      Admin about 5 years
  • luthier
    luthier almost 12 years
    I'm trying it and it seems to be working, thanks :) I only need to make a few more tests and then I'll post the results and mark your answer as accepted. Thank you!
  • luthier
    luthier over 11 years
    Not exactly... in the end I created different XML layout files for each Android version, and that seemed to do the trick...
  • luthier
    luthier over 11 years
    That and using the theme AlertDialog.THEME_DEVICE_DEFAULT_LIGHT instead of android.R.style.Theme_Holo_Dialog_NoActionBar :)
  • ashutosh
    ashutosh about 11 years
    Has anyone tried this with custom styles? When I pass in a predefined android style it works, but not if I pass in my own style.. (my custom style is a child of Theme.Dialog)
  • Almer
    Almer about 11 years
    If you don't use the builder at all an alternative way (which worked for me with custom styles) is given: stackoverflow.com/questions/13469084/…
  • Bharat Dodeja
    Bharat Dodeja almost 11 years
    @Blundell I was getting the theme but along with an extra background which I dont want. Below solution worked for me. ContextThemeWrapper context = new ContextThemeWrapper( getActivity(), theme); AlertDialog.Builder builder = new AlertDialog.Builder(context);
  • Vedran Kopanja
    Vedran Kopanja about 10 years
    @Blundell thanks a bunch man, saved me from creating a custom dialog layout! (even though I'll probably do that in the end sigh)
  • Nilzor
    Nilzor over 9 years
    Warning: If you're using .setView() as well, you must get the LayoutInflater from the same wrapped context by calling getSystemService(Context.LAYOUT_INFLATER_SERVICE) for the theme to be applied there as well. Wasted 2 hours to find that out.
  • David
    David about 9 years
    While this code block may answer the question, it would be best if you could provide a little explanation for why it does so.
  • frankelot
    frankelot over 8 years
    The dialog gets created automatically on the DialogFragment class, how do get access to the builder
  • joe_deniable
    joe_deniable about 7 years
    @Nilzor Thanks!
  • fatfatson
    fatfatson almost 5 years
    it's ok. but how could I use DialogFragment.setStyle for choosing style at runtime?
  • Pavitra Kansara
    Pavitra Kansara over 4 years
    @fatfatson you need to apply the setStyle in onCreate. Neither in constructor, nor in onCreateView. Or even better, just override getTheme() with whatever style you want.
  • waseefakhtar
    waseefakhtar about 4 years
    Such a lifesaver!