ventanas tipos studio hacer emergentes edittext diálogos dialogos dialogo crear con como android android-fragments android-dialog android-dialogfragment

hacer - tipos de dialogos en android studio



¿Cómo establecer el ancho y alto de DialogFragment? (21)

Especifico el diseño de mi DialogFragment en un archivo de diseño xml (llamémoslo layout_mydialogfragment.xml ), y sus layout_width y layout_height particularmente (para ser 100dp cada uno digamos). A continuación, infló este diseño en mi método onCreateView(...) siguiente manera:

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

Lamentablemente, me parece que cuando aparece mi cuadro de diálogo (DialogFragment), no respeta el layout_width y el layout_height especificados 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 puedo hacer que mi diálogo respete el layout_width y el layout_height especificados en su archivo de diseño xml? Por el momento, tengo que especificar el ancho y alto de mi diálogo nuevamente en el método onResume() siguiente manera ...

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

... Y, por lo tanto, de forma no deseable, debe recordar realizar cualquier cambio futuro en el ancho y alto del diálogo en dos lugares.


Gotcha # 13: DialogFragment Layouts

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) o onCreateDialog , que no lo hace.

No debes anular ambos métodos, ¡porque es muy probable que confundas a Android con respecto a cuándo y cuándo se infló el diseño de tu diálogo! WTF?

La opción de anular OnCreateDialog o OnCreateView depende de cómo pretenda usar el diálogo.

  • Si inicia 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 es menos común), se espera que anule OnCreateView .

Esto es posiblemente lo peor del mundo.

onCreateDialog Locura

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

Que comience la locura.

Cuando sobrescribe en onCreateDialog , Android IGNORA COMPLETAMENTE varios atributos del nodo raíz del .xml Layout que infle. Esto incluye, pero probablemente no se limite a:

  • background_color
  • layout_gravity
  • layout_width
  • layout_height

Esto es casi cómico, ya que se requiere que establezca el layout_width y el layout_height de CADA .xml Layout o Android Studio le dará una pequeña insignia roja de vergüenza.

Solo la palabra DialogFragment me da ganas de vomitar. Podría escribir una novela llena de trampas y errores de Android, pero esta es una de las más intrépidas.

Para volver a la sensatez, primero, declaramos un estilo para restaurar SOLO el background_color y el layout_gravity que 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 para Diálogos (en el tema de AppCompat en este ejemplo).

A continuación, aplicamos el estilo mediante programación para recuperar los valores que acaba de abandonar Android y restaurar el aspecto y la sensación estándar de AlertDialog :

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 parecerse a AlertDialog . Tal vez esto es lo suficientemente bueno.

¡Pero espera hay mas!

Si está buscando establecer un layout_width o layout_height para su AlertDialog cuando se muestre (muy probablemente), entonces adivine qué, ¡aún no ha terminado!

La hilaridad continúa cuando te das cuenta de que si intentas establecer un layout_width o un layout_width específicos en tu nuevo y elegante estilo, Android también 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 alto de ventana ESPECÍFICO, puede dirigirse a un método completo 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, solo para girar a la derecha y lanzar ViewGroup.LayoutParams nuevo a WindowManager.LayoutParams unas líneas más adelante. El Java efectivo no puede ser condenado, el casting innecesario no ofrece NADA más que hacer que el código sea aún más difícil de descifrar.

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

En resumen

Para DialogFragment s que anula onCreateDialog :

  • Para restablecer el aspecto y la sensación estándar de AlertDialog , cree un estilo que establezca background_color = transparent y layout_gravity = center y aplique ese estilo en onCreateDialog .
  • Para establecer un layout_width y / o layout_height , hágalo mediante programación en onResume con LayoutParams
  • Para mantener la cordura, trata de no pensar en el SDK de Android.

A continuación, puede configurar el ancho y el alto de diseño desde 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();


Aquí hay una manera de establecer el ancho / alto de DialogFragment en xml. Simplemente envuelva su viewHierarchy en un Framelayout (cualquier diseño funcionará) con un fondo transparente.

Un fondo transparente parece ser una bandera especial, ya que centra automáticamente el elemento secundario de frameLayout en la ventana cuando haces eso. Todavía obtendrá el oscurecimiento de la 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"> .....


Creo el diálogo usando AlertDialog.Builder, así que usé la respuesta de Rodrigo dentro de 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)); } });


Cuando necesito hacer que DialogFragment sea un poco más ancho, estoy configurando minWidth:

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


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


Establezca el diseño principal del diseño de diálogo personalizado en RelativeLayout , obtenga ancho y alto comunes automáticamente.

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


Fácil y sólido:

@Override public void onResume() { // Sets the height and the width of the DialogFragment int width = ConstraintLayout.LayoutParams.MATCH_PARENT; int height = ConstraintLayout.LayoutParams.MATCH_PARENT; getDialog().getWindow().setLayout(width, height); super.onResume(); }


La dimensión en el diseño más externo no funciona en el diálogo. Puede agregar un diseño donde establecer 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>


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

Fragmento de la publicación de blog de Adil:

@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 }


Lo arreglé estableciendo los parámetros de diseño del elemento raíz.

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


Obtuve un DialogFragment de tamaño fijo que define lo siguiente en el diseño principal de XML (LinearLayout en mi caso):

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


Para obtener un cuadro de diálogo que cubra casi todo el pedregal: 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; } }

Luego debe 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); }


Puede usar porcentajes para el ancho.

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

Usé Holo Theme para este ejemplo.


Sé que esto es antiguo, pero la solución más limpia que he encontrado es anular en onCreateDialog() lugar de onCreateView() . Lo que hace que mi respuesta sea diferente es cómo configuro la vista y devuelvo el diálogo. Elimina la necesidad de almacenar / establecer una dimensión, color de fondo, estilo, etc.

@Override public Dialog onCreateDialog(Bundle savedInstanceState) { Dialog dialog = new Dialog(getActivity()); dialog.setContentView(R.layout.fragment_dialog); Button button = (Button) dialog.findViewById(R.id.dialog_button); // ... return dialog; }


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);

Luego, especifique match_parent en su diseño para el diálogo:

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

Solo debe preocuparse por un lugar (colóquelo en su DialogFragment#onResume ). No es perfecto, pero al menos funciona para tener un RelativeLayout como la raíz del archivo de diseño de su diálogo.


Terminé reemplazando a Fragment.onResume() y tomando los atributos del cuadro de diálogo subyacente, luego establecí los parámetros ancho / alto allí. Configuro la altura / ancho del diseño más externo para match_parent . Tenga en cuenta que este código parece respetar también los márgenes que definí en el diseño xml.

@Override public void onResume() { super.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); }


Trabajando en Android 6.0, se encontró con el mismo problema. AlertDialog forma predeterminada el width predefinido establecido en el tema, independientemente del width real establecido en el Layout raíz de la vista personalizada. Pude hacer que se ajustara correctamente ajustando el width de la TextView . Sin investigar más, parece que dimensionar los elementos reales y tener el ajuste de Layout raíz a su alrededor lo hace funcionar como se esperaba. A continuación se muestra un diseño 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>


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

(Asegúrese de ver su solución) Esta fue su solución. Haga clic aquí Funcionó, 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 realmente diferente.


Una forma de controlar el ancho y alto de su DialogFragment es asegurarse de que su diálogo respeta el ancho y el alto de su vista si su valor es WRAP_CONTENT .

Usando ThemeOverlay.AppCompat.Dialog

Una forma simple de lograr esto es hacer uso del estilo ThemeOverlay.AppCompat.Dialog que se incluye en la Biblioteca de soporte de Android.

DialogFragment con Dialog :

@NonNull @Override public Dialog onCreateDialog(Bundle savedInstanceState) { LayoutInflater inflater = LayoutInflater.from(getContext()); View view = inflater.inflate(R.layout.dialog_view, null); Dialog dialog = new Dialog(getContext(), R.style.ThemeOverlay_AppCompat_Dialog); dialog.setContentView(view); return dialog; }

DialogFragment con AlertDialog (advertencia: minHeight="48dp" ):

@NonNull @Override public Dialog onCreateDialog(Bundle savedInstanceState) { LayoutInflater inflater = LayoutInflater.from(getContext()); View view = inflater.inflate(R.layout.dialog_view, null); AlertDialog.Builder builder = new AlertDialog.Builder(getContext(), R.style.ThemeOverlay_AppCompat_Dialog); builder.setView(view); return builder.create(); }

También puede establecer ThemeOverlay.AppCompat.Dialog como el tema predeterminado al crear sus diálogos, agregándolo al tema xml de su aplicación.
Tenga cuidado, ya que muchos diálogos necesitan el ancho mínimo predeterminado para verse bien.

<!-- Base application theme. --> <style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar"> <!-- For Android Dialog. --> <item name="android:dialogTheme">@style/ThemeOverlay.AppCompat.Dialog</item> <!-- For Android AlertDialog. --> <item name="android:alertDialogTheme">@style/ThemeOverlay.AppCompat.Dialog</item> <!-- For AppCompat AlertDialog. --> <item name="alertDialogTheme">@style/ThemeOverlay.AppCompat.Dialog</item> <!-- Other attributes. --> </style>

DialogFragment con Dialog , haciendo uso de android:dialogTheme :

@NonNull @Override public Dialog onCreateDialog(Bundle savedInstanceState) { LayoutInflater inflater = LayoutInflater.from(getContext()); View view = inflater.inflate(R.layout.dialog_view, null); Dialog dialog = new Dialog(getContext()); dialog.setContentView(view); return dialog; }

DialogFragment con AlertDialog , haciendo uso de android:alertDialogTheme o alertDialogTheme (advertencia: minHeight="48dp" ):

@NonNull @Override public Dialog onCreateDialog(Bundle savedInstanceState) { LayoutInflater inflater = LayoutInflater.from(getContext()); View view = inflater.inflate(R.layout.dialog_view, null); AlertDialog.Builder builder = new AlertDialog.Builder(getContext()); builder.setView(view); return builder.create(); }

Prima

En las API de Android anteriores, los Dialog parecen tener algunos problemas de ancho, debido a su título (incluso si no establece uno).
Si no desea utilizar el estilo ThemeOverlay.AppCompat.Dialog y su Dialog no necesita un título (o tiene uno personalizado), es posible que desee deshabilitarlo:

@NonNull @Override public Dialog onCreateDialog(Bundle savedInstanceState) { LayoutInflater inflater = LayoutInflater.from(getContext()); View view = inflater.inflate(R.layout.dialog_view, null); Dialog dialog = new Dialog(getContext()); dialog.requestWindowFeature(Window.FEATURE_NO_TITLE); dialog.setContentView(view); return dialog; }

Respuesta obsoleta, no funcionará en la mayoría de los casos

Intenté que el diálogo respetara el ancho y alto de mi diseño, sin especificar un tamaño fijo programáticamente.

Pensé que android:windowMinWidthMinor y android:windowMinWidthMajor estaban causando el problema. A pesar de que no estaban incluidos en el tema de mi Activity o Dialog , de alguna manera todavía se estaban aplicando al tema Activity .

Se me ocurrieron tres posibles soluciones.

Solución 1: cree un tema de diálogo personalizado y DialogFragment cuando cree el diálogo en 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: cree un tema personalizado para usar en ContextThemeWrapper que servirá como Context para el diálogo. Úselo si no desea crear un tema de diálogo personalizado (por ejemplo, cuando desea usar 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 ): AlertDialog android:windowMinWidthMinor y android:windowMinWidthMajor en ContextThemeWrapper creado por 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(); }


@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); } }