¿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 …
- Google PlacePicker se cierra inmediatamente después del lanzamiento
- TabHost con Fragmentos y FragmentActivity
- Disposición de la actividad: Clase de fragmento: vs android: atributos de nombre
- El paquete de compatibilidad de Android no incluye Activity.getFragmentManager ()
- Llamada de findViewById en Fragment para encontrar un botón devuelve null
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.
- Los elementos de RecyclerView desaparecen después de cambiar entre fragmentos
- Android: Picasso no carga algunas imágenes
- Agregar un fragmento como encabezado ListView
- La transición de entrada en un fragmento con un elemento compartido se dirige al elemento compartido
- GetTag () devuelve siempre null cuando se llama en fragmento
- ViewPager + FragmentPagerAdapter dentro de un DialogFragment obtiene "IllegalArgumentException: No se encontró ninguna vista ..."
- EXCEPCIÓN FATAL: principal java.lang.NoClassDefFoundError: android.support.v7.internal.widget.TintManager
- Cómo establecer el divisor (a nulo) de un diseño personalizado ListFragment
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
ylayout_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 elViewGroup.LayoutParams
más general, sólo para dar vuelta a la derecha y lanzarViewGroup.LayoutParams
nuevo aWindowManager.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 deLayoutParams
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 deAlertDialog
, cree un estilo que configurebackground_color
=transparent
ylayout_gravity
=center
y aplique ese estilo enonCreateDialog
. - Para establecer un
layout_width
específico y / olayout_height
, hágalo de forma programática enonResume
conLayoutParams
- 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 crear su propia biblioteca para el desarrollo de Android que se utilizará en cada programa que escriba?
- Evitar que ViewPager destruya vistas fuera de pantalla