¿Cómo configurar el ancho y la altura de DialogFragment?

Especifico el diseño de mi DialogFragment en un archivo de diseño xml (llamémosle layout_mydialogfragment.xml ), y sus layout_width y layout_height particular (para ser 100dp cada digamos). Luego hincho este diseño en el método onCreateView de mi onCreateView(...) como sigue:

 View view = inflater.inflate(R.layout.layout_mydialogfragment, container, false); 

Desafortunadamente, cuando mi diálogo (DialogFragment) aparece, no respeta el layout_width y layout_height especificado en su archivo de diseño xml (y mi diálogo se reduce o se expande de forma variable según el contenido). ¿Alguien sabe si o cómo puedo obtener mi diálogo para respetar el layout_width y layout_height especificado en su archivo de diseño xml? Por el momento estoy teniendo que especificar el ancho y la altura de mi diálogo de nuevo en el método onResume() mi DialogFragment como sigue …

 getDialog().getWindow().setLayout(width, height); 

… Y así, indeseablemente, tiene que recordar hacer cualquier cambio futuro a la anchura y altura del diálogo en dos lugares.

Si convierte directamente desde valores de recursos:

 int width = getResources().getDimensionPixelSize(R.dimen.popup_width); int height = getResources().getDimensionPixelSize(R.dimen.popup_height); getDialog().getWindow().setLayout(width, height); 

A continuación, especifique match_parent en su diseño para el cuadro de diálogo:

 android:layout_width="match_parent" android:layout_height="match_parent" 

Sólo tienes que preocuparte por un lugar (colocarlo en tu DialogFragment#onResume ). No es perfecto, pero al menos funciona para tener un RelativeLayout como la raíz del archivo de diseño del diálogo.

Tengo un tamaño fijo DialogFragment que define lo siguiente en la disposición principal de XML (LinearLayout en mi caso):

 android:layout_width="match_parent" android:layout_height="match_parent" android:minWidth="1000dp" android:minHeight="450dp" 

Terminé anulando Fragment.onResume() y agarrando los atributos del diálogo subyacente, después fijando los parámetros del anchura / de la altura allí. match_parent altura / anchura más externa de la disposición al match_parent . Tenga en cuenta que este código parece respetar los márgenes que definí en el diseño xml.

 @Override public void onResume() { ViewGroup.LayoutParams params = getDialog().getWindow().getAttributes(); params.width = LayoutParams.MATCH_PARENT; params.height = LayoutParams.MATCH_PARENT; getDialog().getWindow().setAttributes((android.view.WindowManager.LayoutParams) params); super.onResume(); } 

Lo único que funcionó en mi caso fue la solución señalada aquí: http://adilatwork.blogspot.mx/2012/11/android-dialogfragment-dialog-sizing.html

Snippet de Adil entrada en el blog:

 @Override public void onStart() { super.onStart(); // safety check if (getDialog() == null) return; int dialogWidth = ... // specify a value here int dialogHeight = ... // specify a value here getDialog().getWindow().setLayout(dialogWidth, dialogHeight); // ... other stuff you want to do in your onStart() method } 

Estaba tratando de hacer que el diálogo respetar el ancho y la altura de mi diseño, sin especificar un tamaño fijo mediante programación.

Me imaginé que android:windowMinWidthMinor y android:windowMinWidthMajor estaban causando el problema. A pesar de que no fueron incluidos en el tema de mi Activity o Dialog , todavía estaban siendo aplicados al tema de la Activity , de alguna manera.

He planteado tres posibles soluciones.

Solución 1: cree un tema de diálogo personalizado y utilícelo al crear el diálogo en el DialogFragment .

 <style name="Theme.Material.Light.Dialog.NoMinWidth" parent="android:Theme.Material.Light.Dialog"> <item name="android:windowMinWidthMinor">0dip</item> <item name="android:windowMinWidthMajor">0dip</item> </style> 
 @Override public Dialog onCreateDialog(Bundle savedInstanceState) { return new Dialog(getActivity(), R.style.Theme_Material_Light_Dialog_NoMinWidth); } 

Solución 2: crear un tema personalizado que se utilizará en un ContextThemeWrapper que servirá como Context para el diálogo. Use esto si no desea crear un tema de diálogo personalizado (por ejemplo, cuando desee utilizar el tema especificado por android:dialogTheme ).

 <style name="Theme.Window.NoMinWidth" parent=""> <item name="android:windowMinWidthMinor">0dip</item> <item name="android:windowMinWidthMajor">0dip</item> </style> 
 @Override public Dialog onCreateDialog(Bundle savedInstanceState) { return new Dialog(new ContextThemeWrapper(getActivity(), R.style.Theme_Window_NoMinWidth), getTheme()); } 

Solución 3 (con un AlertDialog ): aplicar android:windowMinWidthMinor y android:windowMinWidthMajor en el ContextThemeWrapper creado por el AlertDialog$Builder .

 <style name="Theme.Window.NoMinWidth" parent=""> <item name="android:windowMinWidthMinor">0dip</item> <item name="android:windowMinWidthMajor">0dip</item> </style> 
 @Override public final Dialog onCreateDialog(Bundle savedInstanceState) { View view = new View(); // Inflate your view here. AlertDialog.Builder builder = new AlertDialog.Builder(getActivity()); builder.setView(view); // Make sure the dialog width works as WRAP_CONTENT. builder.getContext().getTheme().applyStyle(R.style.Theme_Window_NoMinWidth, true); return builder.create(); } 

Cuando necesito hacer el DialogFragment un poco más ancho estoy fijando minWidth:

 <LinearLayout android:layout_width="match_parent" android:layout_height="match_parent" android:minWidth="320dp" ... /> 

Gotcha # 13: DialogFragment

Es una especie de entumecimiento de la mente realmente.

Al crear un DialogFragment , puede optar por anular onCreateView (que pasa un ViewGroup para adjuntar su diseño .xml a) o onCreateDialog , que no.

No debe anular los dos métodos tho, porque es muy probable confundir Android en cuanto a cuándo o si el diseño de su diálogo se infló! ¿WTF?

La opción de reemplazar OnCreateDialog o OnCreateView depende de cómo se va a utilizar el diálogo.

  • Si va a iniciar el diálogo en una ventana (el comportamiento normal), se espera que anule OnCreateDialog .
  • Si tiene la intención de incrustar el fragmento de diálogo dentro de un diseño de interfaz de usuario existente (FAR menos común), se espera que reemplace OnCreateView .

Esta es posiblemente la peor cosa en el mundo.

onCreateDialog Insanity

Por lo tanto, está reemplazando onCreateDialog en su DialogFragment para crear una instancia personalizada de AlertDialog para mostrar en una ventana. Guay. Pero recuerde, onCreateDialog no recibe ViewGroup para adjuntar su diseño .xml personalizado a . No hay problema, simplemente pasar null al método de inflate .

Que comience la locura.

Cuando anula onCreateDialog , Android COMPLETAMENTE IGNORA varios atributos del nodo raíz del Diseño .xml que infla. Esto incluye, pero probablemente no se limita a:

  • background_color
  • layout_gravity
  • layout_width
  • layout_height

Esto es casi cómico, ya que se requiere para establecer el layout_width y layout_height de EVERY. layout_height Layout o Android Studio le dará una bofetada con una pequeña insignia roja agradable de la vergüenza.

Sólo la palabra DialogFragment me hace querer vomitar. Podría escribir una novela llena de Android gotchas y snafus, pero este es uno de los más innerous.

Para volver a la cordura, en primer lugar, declaramos un estilo para restaurar sólo el background_color y layout_gravity esperamos:

 <style name="MyAlertDialog" parent="Theme.AppCompat.Dialog"> <item name="android:windowBackground">@android:color/transparent</item> <item name="android:layout_gravity">center</item> </style> 

El estilo anterior hereda del tema base de Diálogos (en el tema de AppCompat en este ejemplo).

A continuación, aplicamos el estilo de forma programática para poner de nuevo los valores de Android sólo echados a un lado y restaurar el aspecto estándar AlertDialog y sentir:

 public class MyDialog extends DialogFragment { @Override public Dialog onCreateDialog(Bundle savedInstanceState) { View layout = getActivity().getLayoutInflater().inflate(R.layout.my_dialog_layout, null, false); assert layout != null; //build the alert dialog child of this fragment AlertDialog.Builder b = new AlertDialog.Builder(getActivity()); //restore the background_color and layout_gravity that Android strips b.getContext().getTheme().applyStyle(R.style.MyAlertDialog, true); b.setView(layout); return b.create(); } } 

El código anterior hará que su AlertDialog vea como un AlertDialog nuevo. Tal vez esto es lo suficientemente bueno.

¡Pero espera hay mas!

Si usted está buscando para establecer un layout_width o layout_height para su AlertDialog cuando se muestra (muy probable), entonces adivina qué, no ha terminado todavía!

La hilaridad continúa cuando te das cuenta de que si intentas establecer un layout_width específico o layout_height en tu nuevo estilo elegante, Android lo ignorará por completo:

 <style name="MyAlertDialog" parent="Theme.AppCompat.Dialog"> <item name="android:windowBackground">@android:color/transparent</item> <item name="android:layout_gravity">center</item> <!-- NOPE!!!!! ---> <item name="android:layout_width">200dp</item> <!-- NOPE!!!!! ---> <item name="android:layout_height">200dp</item> </style> 

Para establecer un ancho o altura de ventana ESPECÍFICA, se llega a la cabeza de más de un método completo 'nuther y tratar con LayoutParams :

 @Override public void onResume() { super.onResume(); Window window = getDialog().getWindow(); if(window == null) return; WindowManager.LayoutParams params = window.getAttributes(); params.width = 400; params.height = 400; window.setAttributes(params); } 

Muchas personas siguen el mal ejemplo de Android de lanzar WindowManager.LayoutParams hasta el ViewGroup.LayoutParams más general, sólo para dar vuelta a la derecha y lanzar ViewGroup.LayoutParams nuevo a WindowManager.LayoutParams unas líneas más tarde. Eficaz Java ser condenado, que casting innecesario ofrece nada más que hacer que el código aún más difícil de descifrar.

Nota: Hay LayoutParams repeticiones de LayoutParams en el SDK de Android, un ejemplo perfecto de diseño radicalmente pobre.

En resumen

Para DialogFragment s que anulan onCreateDialog :

  • Para restaurar la AlertDialog estándar de AlertDialog , cree un estilo que configure background_color = transparent y layout_gravity = center y aplique ese estilo en onCreateDialog .
  • Para establecer un layout_width específico y / o layout_height , hágalo de forma programática en onResume con LayoutParams
  • Para mantener la cordura, intenta no pensar en el SDK de Android.

Lo fijo fijando los parámetros de la disposición del elemento de la raíz.

 int width = activity.getResources().getDisplayMetrics().widthPixels; int height = activity.getResources().getDisplayMetrics().heightPixels; content.setLayoutParams(new LinearLayout.LayoutParams(width, height)); 

Esta es una manera de establecer DialogFragment width / height en xml. Simplemente envuelva su visiónHierarchy en un Framelayout (cualquier diseño funcionará) con un fondo transparente.

Un fondo transparente parece ser una bandera especial, porque automáticamente centra el niño frameLayout en la ventana cuando lo haces. Usted todavía obtendrá el oscurecimiento de pantalla completa detrás de su fragmento, indicando que su fragmento es el elemento activo.

 <?xml version="1.0" encoding="utf-8"?> <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:background="@color/transparent"> <RelativeLayout android:layout_width="match_parent" android:layout_height="300dp" android:background="@color/background_material_light"> ..... 

La dimensión en el diseño más externo no funciona en el diálogo. Puede agregar un diseño donde se establezca la dimensión debajo de la más externa.

 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="wrap_content" android:layout_height="wrap_content"> <LinearLayout android:layout_width="xxdp" android:layout_height="xxdp" android:orientation="vertical"> </LinearLayout> 

Creo el diálogo usando AlertDialog.Builder así que usé la respuesta de Rodrigo dentro de un OnShowListener.

 dialog.setOnShowListener(new OnShowListener() { @Override public void onShow(DialogInterface dialogInterface) { Display display = getWindowManager().getDefaultDisplay(); DisplayMetrics outMetrics = new DisplayMetrics (); display.getMetrics(outMetrics); dialog.getWindow().setLayout((int)(312 * outMetrics.density), (int)(436 * outMetrics.density)); } }); 

En mi caso fue causado por align_parentBottom="true" dado a una vista dentro de un RelativeLayout . Se eliminó todo el alignParentBottom y cambió todos los diseños a LinearLayouts verticales y el problema desapareció.

Trabajando en Android 6.0, se encontró con el mismo problema. AlertDialog predeterminaría el width predefinido establecido en el tema independientemente del width real establecido en el Layout raíz de la vista personalizada. Fui capaz de conseguir que se establezca correctamente el ajuste de la width de la TextView loading_message . Sin investigar más, parece que el tamaño de los elementos reales y tener la raíz Layout alrededor de ellos hace que funcione como se esperaba. A continuación se muestra una disposición XML de un diálogo de carga que establece el width del diálogo correctamente. Usando esta biblioteca para la animación.

 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="wrap_content" android:layout_height="wrap_content" android:background="@color/custom_color" android:padding="@dimen/custom_dimen"> <com.github.rahatarmanahmed.cpv.CircularProgressView xmlns:app="http://schemas.android.com/apk/res-auto" android:id="@+id/progress_view" android:layout_width="40dp" android:layout_height="40dp" android:layout_centerHorizontal="true" app:cpv_color="@color/white" app:cpv_animAutostart="true" app:cpv_indeterminate="true" /> <TextView android:id="@+id/loading_message" android:layout_width="100dp" android:layout_height="wrap_content" android:layout_below="@+id/progress_view" android:layout_centerHorizontal="true" android:gravity="center" android:textSize="18dp" android:layout_marginTop="@dimen/custom_dimen" android:textColor="@color/white" android:text="@string/custom_string"/> </RelativeLayout> 

Usted puede debajo de código para fijar el ancho y la altura de la disposición de java.

 final AlertDialog alertDialog = alertDialogBuilder.create(); final WindowManager.LayoutParams WMLP = alertDialog.getWindow().getAttributes(); WMLP.gravity = Gravity.TOP; WMLP.y = mActionBarHeight; WMLP.x = getResources().getDimensionPixelSize(R.dimen.unknown_image_width); alertDialog.getWindow().setAttributes(WMLP); alertDialog.show(); 

Puede usar el porcentaje de ancho.

 <style name="Theme.Holo.Dialog.MinWidth"> <item name="android:windowMinWidthMajor">70%</item> 

He utilizado el tema de Holo para este ejemplo.

Establezca el diseño de Parent del diseño de diálogo personalizado en RelativeLayout , obtenga anchura y altura comunes automáticamente.

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

Una de las soluciones anteriores casi funcionó. Intenté algo ligeramente diferente y terminó trabajando para mí.

(Asegúrese de mirar su solución) Esta fue su solución .. Haga clic aquí Trabajó excepto para: builder.getContext (). GetTheme (). ApplyStyle (R.style.Theme_Window_NoMinWidth, true);

Lo cambié a

  @Override public Dialog onCreateDialog(Bundle savedInstanceState) { // Use the Builder class for convenient dialog construction AlertDialog.Builder builder = new AlertDialog.Builder(getActivity()); // Get layout inflater LayoutInflater layoutInflater = getActivity().getLayoutInflater(); // Set layout by setting view that is returned from inflating the XML layout builder.setView(layoutInflater.inflate(R.layout.dialog_window_layout, null)); AlertDialog dialog = builder.create(); dialog.getContext().setTheme(R.style.Theme_Window_NoMinWidth); 

La última línea es lo que es realmente diferente.

 @Override public void onStart() { super.onStart(); Dialog dialog = getDialog(); if (dialog != null) { dialog.getWindow().setLayout(-1, -2); dialog.getWindow().getAttributes().windowAnimations = R.style.DialogAnimation; Window window = getDialog().getWindow(); WindowManager.LayoutParams params = window.getAttributes(); params.dimAmount = 1.0f; window.setAttributes(params); window.setBackgroundDrawableResource(android.R.color.transparent); } } 

Para obtener un Diálogo que cubre casi todo el scree: Primero defina una clase ScreenParameter

 public class ScreenParameters { public static int Width; public static int Height; public ScreenParameters() { LayoutParams l = new LayoutParams(LayoutParams.MATCH_PARENT,LayoutParams.MATCH_PARENT); Width= l.width; Height = l.height; } } 

Entonces usted tiene que llamar al ScreenParamater antes de su método getDialog.getWindow (). SetLayout ()

 @Override public void onResume() { super.onResume(); ScreenParameters s = new ScreenParameters(); getDialog().getWindow().setLayout(s.Width , s.Height); } 
  • Cómo cambiar la pestaña Color del indicador por programa
  • Actividad vs Fragmento Ciclo de vida
  • ¿Cómo implementar onBackPressed () & intenciones en el fragmento?
  • Establecer fuente personalizada para fragmentos de Android
  • Cómo puedo establecer un intervalo de minutos en DialogFragment
  • Reemplazar fragmento en ViewPager muestra pantalla en blanco?
  • Reemplazar la barra de herramientas para cada fragmento de cajón de navegación
  • Cómo agregar / quitar Fragmento en el botón haga clic?
  • Posición de DialogFragment en Android
  • ¿Por qué se recomienda no retener el fragmento con la interfaz de usuario?
  • OnActivityResult () no se llama
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.