Software Development

Pro tip: Unravel the mystery of Android's full screen dialog fragments

Android dialog fragments are just a wrapper around a standard dialog, which can make it confusing why they ignore full screen width and height parameters in a custom XML layout.

androidlogo051914.jpg

Fragments solve a great number of problems with Android's wide array of display support, but they can be confusing. Compound that with the recommendation to replace all your dialogs with dialog fragments, and it is easy to find yourself throwing up your hands in frustration.

A common issue for developers new to dialog fragments is how to display a dialog full screen. Since dialog fragments must return a view in the create view override, it would seem that assigning a custom layout with a width and height of match parent would do the trick. Alas, it does not.

In fact, no amount of manipulating the XML layout file alone will give you the desired effect. The reason is that dialog fragments are only a wrapper to hold a dialog. So it is the window, not the container, that needs to be adjusted at run time.

The following demonstration is the result of a great deal of googling, a lot of trial, and a fair share of error. Follow along with the step-by-step guide, or download and import the entire project into Eclipse.

1. Create a new Android project in Eclipse. Target SDK 14 (ICS) or higher.

2. In the /res/values/styles.xml file, add a custom style for your dialog.

styles.xml
<resources>

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

    
<style name="AppTheme" parent="AppBaseTheme">
    
</style>
    
    <style name="MY.DIALOG" parent="android:Theme" >
	    <item name="android:windowNoTitle">true</item>
	    <item name="android:windowFullscreen">true</item>
	    <item name="android:windowIsFloating">false</item>
	</style>

</resources>

3. In the /res/layout folder we will be creating two layouts: one for the activity and one for the dialog.

activity_main.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <Button
        android:id="@+id/button"
        android:layout_centerInParent="true"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Launch Dialog" />

</RelativeLayout>

my_fragment.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <TextView
        android:id="@+id/label"
        android:layout_centerInParent="true"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Hello Full Screen Dialog Fragment" />

</RelativeLayout>

4. In /src the MainActivity.java file contains the definition for both the activity and the dialog fragment. It is the combination of the parameters set in the on create and on start methods of the MyFragment inner class that produces the desired effect.

MainActicity.java
package com.authorwjf.fsdiagfrag;

import android.os.Bundle;
import android.app.Activity;
import android.app.Dialog;
import android.app.DialogFragment;
import android.app.FragmentTransaction;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;

public class MainActivity extends Activity implements OnClickListener {

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		 findViewById(R.id.button).setOnClickListener(this);
	}
	
	@Override
	public void onClick(View v) {
		FragmentTransaction ft = getFragmentManager().beginTransaction();
		MyDialogFragment frag = new MyDialogFragment();
		frag.show(ft, "txn_tag");
	}

	static public class MyDialogFragment extends DialogFragment {
		
		@Override
	    public void onCreate(Bundle savedInstanceState) {
	        super.onCreate(savedInstanceState);
	        setStyle(DialogFragment.STYLE_NORMAL, R.style.MY_DIALOG);
		}
		
		@Override 
		public void onStart() {
	        super.onStart();
	        Dialog d = getDialog();
	        if (d!=null){
	        	int width = ViewGroup.LayoutParams.MATCH_PARENT;
	        	int height = ViewGroup.LayoutParams.MATCH_PARENT;
	            d.getWindow().setLayout(width, height);
	        }
	    }
		
		 @Override
		    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
		        View root = inflater.inflate(R.layout.my_fragment, container, false);
		        return root;
		 }
		
	}

}

Running the application will launch the activity (Figure A).

Figure A

androiddiagfrag1051614.png

Tapping the button will launch the full screen dialog (Figure B).

Figure B

androiddiagfrag2051614.png

For readers targeting a platform older than Ice Cream Sandwich, I confirmed the above technique also works with the V4 compatibility library. The tricky part is not the code but knowing what bits to flip.

I hope this quick walk-through saves my fellow Android developers a few keystrokes.

Also see

About

William J Francis began programming computers at age eleven. Specializing in embedded and mobile platforms, he has more than 20 years of professional software engineering under his belt, including a four year stint in the US Army's Military Intellige...

1 comments
DdZ
DdZ

Wahouu!! I have an image gallery in my dialogfragment and the size of the window was set inside the onResume method and this using DisplayMetrics but really bad performances, the gallery was really slow in Landscape mode, now this is perfect! Thanks a lot!