how to programatically theme an activity to be like a dialog?

Background

The Activity behind an Acivity is drawn if the foreground activity’s theme according to its AndroidManifest.xml is a dialog; otherwise the android os will not draw the Activity behind it (probably to save memory since it usually won’t be seen anyway).

To exploit this, we set the theme of our Acitvity to a dialog in the manifest, making the android os draw the Activity behind it, but later, programatically set our Activity‘s theme to whatever we like at runtime.

Example on github

I made an example and put it on github.

Tutorial

Step 1: create two custom themes for your application in styles.xml. One for normal activities, and another for dialog activities. It is important for the custom dialog theme to inherit from a base theme that is also a dialog. In my case, the parent theme is Base.Theme.AppCompat.Light.Dialog.FixedSize). Here is my styles.xml:

<resources>

    <!-- custom normal activity theme -->    
    <style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
    </style>

    <!-- custom dialog activity theme -->
    <style name="AppTheme.Dialog" parent="Base.Theme.AppCompat.Light.Dialog.FixedSize">
        <!-- removing the dialog's action bar -->
        <item name="windowActionBar">false</item>
        <item name="windowNoTitle">true</item>
    </style>

</resources>

Step 2: in the AndroidManifest.xml, set the theme of the Activity in question to any dialog theme. This makes the android os think that the Activity is a dialog, so it will draw the Activity behind it, and not black it out. In my case, I used Theme.AppCompat.Dialog. Below is my AndroidManifest.xml:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
          package="com.example.eric.questiondialog_artifact">

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name">
        <activity
            android:name=".DialogActivity"
            android:label="@string/app_name"
            android:theme="@style/Theme.AppCompat.Dialog"> <-- IMPORTANT!!! -->
            <intent-filter>
                <action android:name="android.intent.action.MAIN"/>
                <category android:name="android.intent.category.LAUNCHER"/>
            </intent-filter>
        </activity>
    </application>

</manifest>

Step 3: in the actual activity, set the theme programatically to either the theme for normal activities, or the theme for dialogs. My DialogActivity.java is below:

package com.example.eric.questiondialog_artifact;

import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;

public class DialogActivity extends AppCompatActivity
{
    @Override
    protected void onCreate(Bundle savedInstanceState)
    {
        setTheme(R.style.AppTheme_Dialog); // can either use R.style.AppTheme_Dialog or R.style.AppTheme as deined in styles.xml
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_dialog);
    }
}

Leave a Comment