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

173

Especifico el diseño de mi DialogFragment en un archivo de diseño xml (llamémosle layout_mydialogfragment.xml), y su layout_widthy layout_heightatributos particular (para ser 100dpejemplo de cada LET). Luego inflo este diseño en el onCreateView(...)método de mi DialogFragment de la siguiente manera:

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

Desafortunadamente, encuentro que cuando aparece mi cuadro de diálogo (DialogFragment), no respeta el layout_widthy layout_heightespecificado en su archivo de diseño xml (y mi cuadro de diálogo se reduce o se expande de forma variable según el contenido). ¿Alguien sabe si o cómo puedo hacer que mi diálogo respete layout_widthy layout_heightespecifique en su archivo de diseño xml? Por el momento, tengo que especificar el ancho y la altura de mi diálogo nuevamente en el onResume()método de mi DialogFragment de la siguiente manera ...

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

... Y por lo tanto, indeseablemente, debemos recordar hacer cualquier cambio futuro al ancho y alto del diálogo en dos lugares.

Adil Hussain
fuente
2
Considere aceptar la respuesta de jpmcosta. No es un truco y en realidad soluciona el problema.
Bogdan Zurac

Respuestas:

168

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 tiene que preocuparse por un lugar (colóquelo en su DialogFragment#onResume). No es perfecto, pero al menos funciona para tener un RelativeLayout como raíz del archivo de diseño de su cuadro de diálogo.

Blix247
fuente
3
Esta respuesta no funciona en mi caso (para DialogFragment). Tuve que usar los parámetros de FragmentLayout para cambiar el tamaño de la ventana de visualización.
Rusfearuth
3
Tuve que ajustar mi diseño RelativeLayouty me ayudó. Muchas gracias por la solución, me ahorró mucho tiempo.
Johnny Doe
62
Esto funciona muy bien para mí (Android 4.0+), una vez que me di cuenta de que esto debe estar onResume(), no onCreateView(). (Mi diseño raíz es RelativeLayout envuelto en un ScrollView).
Jonik
14
Útil en algunos casos: use todo el ancho de la pantalla:int width = getResources().getDisplayMetrics().widthPixels
Jonik
66
+1 para Jonik. -1 para Richard. Siempre uso fragmentos de soporte y nunca he podido hacer que esto funcione onCreateDialog(). Necesita estar adentro onResume().
MinceMan
146

Terminé anulando Fragment.onResume()y tomando los atributos del diálogo subyacente, luego establecí parámetros de ancho / alto allí. Configuré la altura / anchura del diseño más externo en match_parent. Tenga en cuenta que este código también parece respetar 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);
}
jmaculate
fuente
2
Gracias ! Esto funciona para mi ! Además, esta es una forma elegante de hacerlo.
AntoineP
1
@jmaculate - Pregunta rápida: cuando estás lanzando (android.view.WindowManager.LayoutParams), ¿de qué lo estás lanzando? Me sorprendió elegir la importación correcta para LayoutParamsaparecer en las primeras 3 líneas de la función. Terminé eligiendo (android.view.WindowManager.LayoutParams). ¿Se supone que esto es correcto?
Dev-iL
@ Dev-iL getAttributes () devuelve un WindowManger.LayoutParams, pero en mi caso lo envié implícitamente a ViewGroup.LayoutParams porque eso es todo lo que necesito (Java efectivo, Elemento 52)
Editaré
1
Si necesita lanzarlo nuevamente android.view.WindowManager.LayoutParams, es inútil usar ViewGroup.LayoutParamstres líneas arriba ... No gana ninguna flexibilidad aquí. Lo que sea, gracias por esta buena respuesta!
Kevin Robatel
2
Esta es la mejor solución. Incluso puede usar un valor específico de píxeles junto con MATCH_PARENT o WRAP_CONTENT.
Koesh
98

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

android:layout_width="match_parent"
android:layout_height="match_parent"
android:minWidth="1000dp"
android:minHeight="450dp"
Jose_GD
fuente
44
Descubrí que necesitaba el ancho medio y la altura mínima en Honeycomb, pero no en ICS.
daveywc
1
Esto parece funcionar a primera vista, pero probablemente debería evitarse. La vista continuará fuera de la pantalla dependiendo del ancho del dispositivo, por lo que si tiene botones en la esquina inferior derecha, no aparecerán.
CodyEngel
La vista NO continúa fuera de la pantalla. El sistema Android parece asegurarse de que el DialogFragment permanezca dentro de los límites de la vista (con un pequeño margen), incluso si estos límites son más pequeños que el minWidth y minHeight especificados.
Lensflare
51

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 del 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
}
Rodrigo
fuente
Solución perfecta y muy bien explicada en el blog.
varun bhardwaj
+1 getDialog().getWindow().setLayout(dialogWidth, dialogHeight); funciona perfectamente para un DialogFragment. Pero no entiendo el control de seguridad. ¿Por qué tenemos que verificar null?
tpk
3
@ 2943 - simplemente porque no hay garantía de que el Dialog(un hijo del DialogFragment) estará disponible en el momento en que se solicite. Es posible que Android regrese nulo cuando llamemos getDialog().
rmirabelle
@mirabelle si está esperando la devolución de llamada onStart del cuadro de diálogo, ¿cómo puede ser nulo?
rommex
49

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

Utilizando ThemeOverlay.AppCompat.Dialog

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

DialogFragmentcon 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;
}

DialogFragmentcon 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.Dialogcomo tema predeterminado al crear sus cuadros de diálogo, agregándolo al tema xml de su aplicación.
Tenga cuidado, ya que muchos cuadros de diálogo 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>

DialogFragmentcon 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;
}

DialogFragmentcon AlertDialog, haciendo uso de android:alertDialogThemeo 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 Dialogs parecen tener algunos problemas de ancho debido a su título (incluso si no configura uno).
Si no desea utilizar el ThemeOverlay.AppCompat.Dialogestilo y Dialogno necesita un título (o tiene uno personalizado), puede 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 desactualizada, no funcionará en la mayoría de los casos

Estaba tratando de hacer que el diálogo respetara el ancho y la altura de mi diseño, sin especificar un tamaño fijo programáticamente.

Me di cuenta de eso android:windowMinWidthMinory android:windowMinWidthMajorestaba causando el problema. Aunque no se incluyeron en el tema de mi Activityo Dialog, todavía se aplicaban al Activitytema, de alguna manera.

Se me ocurrieron tres posibles soluciones.

Solución 1: cree un tema de diálogo personalizado y úselo 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 utilizarlo en uno ContextThemeWrapperque sirva como Contextdiálogo. Use esto 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): hacer cumplir android:windowMinWidthMinory android:windowMinWidthMajoren lo ContextThemeWrappercreado 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();
}
jpmcosta
fuente
44
Realmente no sé por qué demonios esta no es la respuesta aceptada. Esta es literalmente LA única respuesta que funciona y no es un truco (estoy hablando principalmente de su primera solución).
Bogdan Zurac
1
desafortunadamente, esto solo lo encontré después de pasar una hora pensando cómo resolverlo.
brainvision
La solución 3 me salva la vida. Muchas gracias
Simon
Pude reproducir su problema en las API de Android anteriores. Se agregaron algunas alternativas que podrían ayudarlo.
jpmcosta
La solución 1 funcionó para mí. Acabo de usar Theme.MaterialComponents.Light.Dialogcomo padre y usé este estilo en el constructor de MaterialAlertDialogBuilder. Tropecé con su respuesta después de una investigación de 1 hora. Gracias y aprobado.
Shahood ul Hassan
39

Gotcha # 13: DialogFragmentDiseños

Es una especie de mente adormecedora realmente.

Al crear un DialogFragment, puede optar por anular onCreateView(que pasa un ViewGrouppara adjuntar su diseño .xml) o onCreateDialog, que no lo hace.

No debe anular ambos métodos, porque es muy probable que confunda Android con respecto a cuándo o si se infló el diseño de su diálogo. WTF?

La elección de anular OnCreateDialogo OnCreateViewdepender de cómo piensa utilizar el diálogo.

  • Si va a iniciar el cuadro de 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 (MUCHO menos común), se espera que anule OnCreateView.

Esto es posiblemente lo peor del mundo.

onCreateDialog Locura

Por lo tanto, está anulando onCreateDialogen su DialogFragmentpara crear una instancia personalizada AlertDialogpara mostrar en una ventana. Frio. Pero recuerde, onCreateDialogno recibe ViewGroupa adjuntar su .xml personalizado diseño a . No hay problema, simplemente pasa nullal inflatemétodo.

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, como se le requiere para establecer el layout_widthy layout_heightde cada .xml Disposición o Android Studio le bofetada con una bonita placa poco rojo de vergüenza.

Solo la palabra DialogFragment me da ganas de vomitar. Podría escribir una novela llena de trucos y problemas de Android, pero esta es una de las más insidiosas.

Para volver a la cordura, primero, declaramos un estilo para restaurar SOLO el background_colory layout_gravityesperamos:

<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 AppCompattema en este ejemplo).

A continuación, aplicamos el estilo mediante programación para recuperar los valores que Android acaba de descartar y restaurar el AlertDialogaspecto estándar :

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 AlertDialogparezca una AlertDialogvez más. Quizás esto sea lo suficientemente bueno.

¡Pero espera hay mas!

Si está buscando establecer un ESPECÍFICO layout_width o layout_heightpara su AlertDialogcuando se muestra (muy probablemente), adivine qué, ¡todavía no ha terminado!

La hilaridad continúa cuando te das cuenta de que si intentas establecer un estilo específico layout_widtho layout_heighten tu nuevo estilo elegante, ¡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, puedes pasar 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 enviar WindowManager.LayoutParamsa los más generales ViewGroup.LayoutParams, solo para dar la vuelta y ViewGroup.LayoutParamsvolver a WindowManager.LayoutParamsunas pocas líneas más tarde. Maldita sea Java, que la conversión innecesaria no ofrece NADA más que hacer que el código sea aún más difícil de descifrar.

Nota al margen: hay unas VEINTE repeticiones LayoutParamsen el SDK de Android, un ejemplo perfecto de diseño radicalmente pobre.

En resumen

Para DialogFragments que anulan onCreateDialog:

  • Para restaurar el AlertDialogaspecto estándar , cree un estilo que establezca background_color= transparenty layout_gravity= centery aplique ese estilo onCreateDialog.
  • Para establecer un específico layout_widthy / o layout_heighthacerlo programáticamente onResumeconLayoutParams
  • Para mantener la cordura, trate de no pensar en el SDK de Android.
rmirabelle
fuente
13
Leer esta respuesta me da ganas de llorar.
Bassinator
3
Amigo, describiste exactamente lo que estoy experimentando en este momento.
Mert Gülsoy
2
Android es una mierda. Te siento hermano. necesitando un contexto para todo, el proceso de la aplicación mata, la falta de bibliotecas de soporte para algunas cosas, la lista continúa
DennisVA
1
@rmirabelle: esta respuesta realmente ayuda, puedes escribir un blog medio y puede ser útil para muchos. En mi caso, estoy usando el diseño de restricción y DialogFragment, por lo que con ignorar en Android 9, debajo de Android 9 está funcionando bien. He agregado - "android: windowMinWidthMajor", "android: windowMinWidthMinor" con estilo y comenzó a funcionar bien.
Rahul
@Rahul medium.com/@rmirabelle/…
rmirabelle
14

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

<LinearLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:minWidth="320dp"
    ... />
Andrey
fuente
1
La mejor solución en mi opinión!
Fabian Knapp
¿Qué pasa si quieres hacerlo más estrecho?
Daniel
8

No veo una razón de peso para anular onResumeo onStartpara ajustar la anchura y la altura del Windowplazo de DialogFragment's Dialog- estos métodos de ciclo de vida en particular puede ser llamado en repetidas ocasiones e innecesariamente ejecutar ese cambio de tamaño de código más de una vez debido a cosas como la conmutación de múltiples ventana, backgrounding luego poner en primer plano la aplicación, y así sucesivamente. Las consecuencias de esa repetición son bastante triviales, pero ¿por qué conformarse con eso?

Establecer el ancho / alto en su lugar dentro de un onActivityCreated()método anulado será una mejora porque este método solo se llama una vez por instancia de su DialogFragment. Por ejemplo:

@Override
public void onActivityCreated(Bundle savedInstanceState) {
    super.onActivityCreated(savedInstanceState);

    Window window = getDialog().getWindow();
    assert window != null;

    WindowManager.LayoutParams layoutParams = window.getAttributes();
    layoutParams.width = ViewGroup.LayoutParams.MATCH_PARENT;
    window.setAttributes(layoutParams);
}

Arriba, acabo de configurar el ancho para que sea match_parentindependiente de la orientación del dispositivo. Si desea que su cuadro de diálogo horizontal no sea tan amplio, puede verificar si está getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAITpreviamente.

N1hk
fuente
6

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>

Kelly
fuente
5

Lo arreglé configurando 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));
Erdem OLKUN
fuente
5

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

Un fondo transparente parece ser una bandera especial, porque automáticamente centra el elemento secundario de frameLayout en la ventana cuando haces eso. Aún obtendrá el oscurecimiento de la pantalla completa detrás de su fragmento, lo que indica 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">

      .....
NameSpace
fuente
Voy a intentar esto porque si funciona de manera consistente, es un enfoque MUY superior para codificar parte del diseño en XML y parte de él en código. Gracias
rmirabelle
Me gusta la idea de este enfoque, pero cuando se prueba, produce un diseño diferente que simplemente cambiar la altura y el ancho mediante programación. Por ejemplo, el ancho total se reduce a la fuerza al ancho máximo que ofrece un AlertDialog (presumiblemente debido a los estilos de Android). Cuando acabo de configurar w y h a través del código, se anula el estilo AlertDialog. Sin embargo, esto puede satisfacer muchas necesidades y es una buena idea. Larga vida al peor SDK de la historia.
rmirabelle
Funcionó muy bien para onCreateView, hasta que quise cambiar el ancho interno a match_parent ...
tudor
5

Aquí está la versión de Kotlin

    override fun onResume() {
        super.onResume()

        val params:ViewGroup.LayoutParams = dialog.window.attributes
        params.width = LinearLayout.LayoutParams.MATCH_PARENT
        params.height = LinearLayout.LayoutParams.MATCH_PARENT
        dialog.window.attributes = params as android.view.WindowManager.LayoutParams
    }
Qadir Hussain
fuente
4

Puede usar el porcentaje para el ancho.

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

Usé Holo Theme para este ejemplo.

StefanoM5
fuente
3

Puede debajo del código para establecer el ancho y la altura del 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();
Ruchit Mittal
fuente
2

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

        });
Jorge García
fuente
(Principalmente para futuros lectores :) Vea el comentario Snicolasen la discusión de " DialogFragmentvs AlertDialog" en stackoverflow.com/a/7979823/3372061 .
Dev-iL
2

Trabajando en Android 6.0, se encontró con el mismo problema. AlertDialogpasaría de forma predeterminada al widthconjunto predefinido en el tema, independientemente del widthconjunto real en la raíz de la vista personalizada Layout. Pude conseguir que se ajustara correctamente ajustando widthel loading_message TextView. Sin investigar más, parece que dimensionar los elementos reales y tener la Layoutenvoltura raíz a su alrededor hace que funcione como se esperaba. A continuación se muestra un diseño XML de un cuadro de diálogo de carga que establece widthcorrectamente el cuadro de diálogo. 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>
C0D3LIC1OU5
fuente
2

Fácil y solido:

@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();
    }
SANAL CAMBAZ
fuente
2

En mi caso DialogFragmentocupaba el tamaño completo de la actividad como a Fragment. El DialogFragmentse basó en el diseño XML, no AlertDialog. Mi error fue agregar el fragmento de diálogo FragmentManagercomo un fragmento habitual:

fragmentManager?.beginTransaction()?.run {
    replace(R.id.container, MyDialogFragment.newInstance(), MyDialogFragment.TAG)
    addToBackStack(MyDialogFragment.TAG)
}?.commitAllowingStateLoss()

En cambio, necesito showel fragmento de diálogo:

val dialogFragment = MyDialogFragment.newInstance()
fragmentManager?.let { dialogFragment.show(it, MyDialogFragment.TAG) }

Después de algunas modificaciones (que tengo ViewPager2en el diseño), el fragmento de diálogo se volvió demasiado estrecho:

ingrese la descripción de la imagen aquí

Usé la solución de N1hk :

override fun onActivityCreated(savedInstanceState: Bundle?) {
    super.onActivityCreated(savedInstanceState)

    dialog?.window?.attributes?.width = ViewGroup.LayoutParams.MATCH_PARENT
}

Ahora ha definido el ancho y la altura, no el tamaño completo de la actividad.

Quiero decir sobre onCreateViewy onCreateDialog. Si tiene un fragmento de diálogo basado en el diseño, puede usar cualquiera de estos 2 métodos.

1) Si usa onCreateView, entonces debe usar onActivityCreatedpara establecer el ancho.

2) Si usa en onCreateDialoglugar de onCreateView, puede establecer parámetros allí. onActivityCreatedNo será necesario.

override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
    super.onCreateDialog(savedInstanceState)

    val view = activity?.layoutInflater?.inflate(R.layout.your_layout, null)

    val dialogBuilder = MaterialAlertDialogBuilder(context!!).apply { // Or AlertDialog.Builder(context!!).apply
        setView(view)
        // setCancelable(false)
    }

    view.text_view.text = "Some text"

    val dialog = dialogBuilder.create()
    // You can access dialog.window here, if needed.

    return dialog
}
CoolMind
fuente
Me salvaste el día, configurar el ancho en onActivityCreated funcionó para mí.
Hagar Magdy
@ManishKumarSharma, ¡buena suerte!
CoolMind
1

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

mehmet6parmak
fuente
1

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

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
vishnuc156
fuente
Esto funcionó para mí. Quería usar un RestraintLayout para diseñar los controles en mi diálogo, así que usé un RelativeLayout para el diseño raíz y luego puse un RestraintLayout directamente dentro de él. Esto me dio un diálogo de tamaño normal. Cuando pongo el RestraintLayout como la raíz sin cambiar nada más, ¡entonces el ancho del diálogo implosionó a no muy ancho!
cortador de hojas el
1

Una de las soluciones anteriores casi funcionó. Intenté algo un poco diferente y terminó funcionando para mí.

(Asegúrese de mirar su solución) Esta fue su solución. Haga clic aquí Funcionó a excepción de: 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.

TheAppFoundry
fuente
0
@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);
    }
}
Alaeddine Khoudi
fuente
0

Esta es la solución más simple.

La mejor solución que he encontrado es anular en onCreateDialog()lugar de onCreateView(). setContentView () establecerá las dimensiones correctas de la ventana antes de inflar. Elimina la necesidad de almacenar / establecer una dimensión, color de fondo, estilo, etc. en archivos de recursos y configurarlos manualmente.

@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;
}
parkgrrr
fuente
0

Añadir a su FragmentDialog:

public void onResume() {
    Window window = getDialog().getWindow();
    Point size = new Point();
    Display display = window.getWindowManager().getDefaultDisplay();
    display.getSize(size);
    window.setLayout( (int)(size.x * 0.9), WindowManager.LayoutParams.WRAP_CONTENT );
    window.setGravity( Gravity.CENTER );
    super.onResume();
}
RonTLV
fuente
0

Esto funcionará perfectamente.

@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);
}
Kishore Reddy
fuente
Esto es más o menos lo que dice la respuesta aceptada de hace más de 3 años.
Adil Hussain
-4

Para obtener un diálogo que cubra casi toda la pantalla: 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);
}
Toye_Brainz
fuente