40

So I have an Activity (say TestActivity) which needs to act as a normal unthemed Activity as well as a Theme.Dialog at other place. I am trying to reuse same TestActivity for both the tasks.

All I am looking for setting the theme dynamically. The code is simple: Here is my activity's onCreate that works with a black background

public void onCreate(Bundle icicle) {
    if (Utility.isDialog == true)
        setTheme(android.R.style.Theme_Dialog);
    super.onCreate(icicle);
    requestWindowFeature(Window.FEATURE_NO_TITLE);
.....

and here is the Manifest Entry

<activity android:name=".TestActivity"/>

And in the meantime I found a post that says it can't be done here is the post http://code.google.com/p/android/issues/detail?id=4394 .But there is a strong feeling that it can be done.

All suggestions are welcome.

Jack A.
  • 4,245
  • 1
  • 20
  • 34
100rabh
  • 6,156
  • 5
  • 27
  • 41
  • Should I accept that there is **no solution** to this question as this [post](http://code.google.com/p/android/issues/detail?id=4394) says? – 100rabh Mar 16 '11 at 10:27

9 Answers9

55

Would like to give a work around for this problem.

Problem : How to use the same activity as both dialog and full screen based.

Solution :

  1. Define your activity in your AndroidManifest.xml with the theme @android:style/Theme.Dialog
  2. In your respective .Java file, check for an intent extra that defines dialog mode.
  3. If it does not exist, set the Theme to android.R.style.Theme. This is the default theme which is applied if you do not define any theme.

Code :

boolean fDialogMode = getIntent().hasExtra("dialog_mode");

if( ! fDialogMode ) {
    super.setTheme(android.R.style.Theme);
}

Alternate Solution:

A more complex solution is to use AlertDialog as below:

  1. Define a ListAdapter class extended from ArrayAdapter.
  2. return 1 in getCount function

    @Override
    public int getCount() { return 1; }
    
  3. In the getView function, inflate the layout of the activity you need and do any customization before returning the view.

    @Override
    public View getView( int position, View view, ViewGroup group ) {
        View v = view;
        if( v == null ) {
            v = getSystemService(Context.LAYOUT_INFLATER_SERVICE).inflate( <layout res id>, null );
        }
    
    ... Do any customization here    ....
    
          return v;
    }
    

This is definitely a second choice option by if you are not doing too much processing in the activity class this could be an option.

Only reason to consider this solution could be that the logic to show it in a dialog is isolated to the places where it is used as a dialog.

Both the options worked for me but for obvious reasons I am taking the first option. :-)

Kapil Rajput
  • 11,429
  • 9
  • 50
  • 65
Deepak G M
  • 1,650
  • 17
  • 12
  • Great explanation, thanks! If someone don't get it at the first time (like me :D) - read @mozarty solution first to understand where exactly you should put this code. – Dmitry Zaytsev Aug 07 '12 at 06:30
45

you can use setTheme(..) before calling setContentView(...)and super.oncreate() and it should work fine

Ahmed Salem
  • 3,947
  • 1
  • 21
  • 40
  • you are not calling setContentView , and i know that it can be done because i did it in my activity – Ahmed Salem Oct 17 '11 at 07:26
  • 4
    Moving the call to setTheme before the super.onCreate made it work for me, thank you! – Bradley Uffner Nov 04 '11 at 18:14
  • Just a FYI: This does work, but it creates an enormous lag in creating a new activity for some reason (on Kindle Fire) and it makes my app crash unexpectedly on the Nook Color. – Joris Weimar Mar 08 '12 at 23:22
  • i never tried it on Kindle before , thx for the info , will have to test it when i get one – Ahmed Salem Mar 09 '12 at 20:13
  • This solution doesn't work for all devices. Consider the Motorola Xoom, the result is a dialog on top of a black background rather than a transparent one. – Cookster Jun 18 '12 at 16:40
  • @user933237 that is interesting , i also found out that what you described happens on ACER iconia tablet – Ahmed Salem Jun 21 '12 at 09:33
11

Like several others, calls to setTheme in onCreate (before or after my call to super.onCreate) did not work. However, by overriding setTheme, I was able to specify a theme other than that stated in Manifest.xml. Specifically, the following worked without issue:

@Override
public void setTheme(int resid) {
    boolean changeTheme = true;
    super.setTheme(changeTheme ? android.R.style.Theme_Dialog : resid);
}

I found the above in the discussion at: https://code.google.com/p/android/issues/detail?id=4394

user3570982
  • 559
  • 1
  • 6
  • 14
  • 1
    However, with Android invoking setTheme() before the onCreate() call, one can't use the data normally sent to an activity to decide whether to change the theme. Some additional hack is needed to make that decision. – Steve B Mar 04 '15 at 21:52
10

Call Activity.setTheme() in onCreate() before you call setContentView().

Reuben Scratton
  • 38,595
  • 9
  • 77
  • 86
  • 2
    Reuben though it works (& I have tried that earlier too)but I see Black Background instead of the calling Activity – 100rabh Feb 11 '11 at 11:19
  • Then your theme properties are incorrect. What is your android:windowBackground set to? – Reuben Scratton Feb 11 '11 at 11:37
  • Reuben I have not defined a custom style.But I will now implement a custom style with windowBackground to color/transparent – 100rabh Feb 14 '11 at 07:18
  • Reuben even the custom style didn't worked.For your answer to windowBackgound see this post http://stackoverflow.com/questions/2176922/how-to-create-transparent-activity-in-android/2700683#2700683 – 100rabh Feb 14 '11 at 09:44
  • 1
    see the updated post with the code.Do let me know for more details. – 100rabh Feb 14 '11 at 13:11
  • is it possible to call the setTheme after setContentView, if i call setContentView again (this time after setTheme) ? example of a scenario: user sees the activity, press a button, and it changes the theme by calling setTheme and then setContentView. – android developer Aug 02 '13 at 23:50
3

use setTheme before calling super.onCreate(savedInstance)

Kapil Rajput
  • 11,429
  • 9
  • 50
  • 65
Mohammad Abu Hmead
  • 621
  • 2
  • 7
  • 18
0

This may not be applicable in your situation, but you can use the theme:

Theme.Holo.DialogWhenLarge

and it will display your activity as a dialog when the screen is large, and as a regular activity when the screen is small. This is covered in the Android documentation on Dialogs and also contains information on programming a Dialog which can also sun as a full screen fragment.

Xebozone
  • 470
  • 6
  • 17
0

Default theme library call:

super.setTheme(android.R.style.Theme);

In my case I was using AppCompat Theme, so make sure that on your id you refer the proper library (i.e.):

super.setTheme(android.support.v7.appcompat.R.style.Theme_AppCompat_NoActionBar);
Zoe
  • 27,060
  • 21
  • 118
  • 148
Victor Oliveira
  • 3,293
  • 7
  • 47
  • 77
-1
setTheme(android.R.style.Theme_Dialog);
Zoe
  • 27,060
  • 21
  • 118
  • 148
Dapper Dan
  • 932
  • 11
  • 23
  • 1
    please take some time to explain how this solves the problem so that other with similar problem can know the issue clearly. – Regolith Jun 17 '19 at 04:49
-1

I know that I am late but I would like to post a solution here:

Check the full source code here. This is the code I used when changing theme...

SharedPreferences pref = PreferenceManager
       .getDefaultSharedPreferences(this);
String themeName = pref.getString("prefSyncFrequency3", "Theme1");
if (themeName.equals("Africa")) {
    setTheme(R.style.AppTheme);
} else if (themeName.equals("Colorful Beach")) {
    //Toast.makeText(this, "set theme", Toast.LENGTH_SHORT).show();
    setTheme(R.style.beach);
} else if (themeName.equals("Abstract")) {
    //Toast.makeText(this, "set theme", Toast.LENGTH_SHORT).show();
    setTheme(R.style.abstract2);
} else if (themeName.equals("Default")) {
    setTheme(R.style.defaulttheme);
}
Artjom B.
  • 61,146
  • 24
  • 125
  • 222
dondondon
  • 881
  • 8
  • 4