Comment définir la largeur et la hauteur de DialogFragment?

Je spécifie la disposition de mon DialogFragment dans un fichier de mise en page XML (appelons-le layout_mydialogfragment.xml ), et ses layout_width et layout_height particulier (à savoir 100dp chacun, par exemple). Je gonfle alors cette disposition dans la méthode onCreateView(...) de onCreateView(...) comme suit:

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

Malheureusement, je trouve que lorsque ma boîte de dialog (DialogFragment) apparaît, elle ne respecte pas le layout_width et le layout_height spécifiés dans son fichier de présentation xml (et ma boîte de dialog se réduit ou s’étend de manière variable en fonction du contenu). Quelqu’un sait-il si ou comment je peux faire en sorte que ma boîte de dialog respecte le layout_width et le layout_height spécifiés dans son fichier de mise en page xml? Pour le moment, je dois spécifier la largeur et la hauteur de ma boîte de dialog à nouveau dans la méthode onResume() de onResume() comme suit …

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

… Et donc, de manière indésirable, vous devez vous souvenir de faire des changements futurs à la largeur et à la hauteur du dialog à deux endroits.

Si vous convertissez directement à partir des ressources:

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

Ensuite, spécifiez match_parent dans votre mise en page pour la boîte de dialog:

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

Vous n’avez qu’à vous soucier d’un seul endroit (placez-le dans votre DialogFragment#onResume ). Ce n’est pas parfait, mais au moins cela fonctionne pour avoir un RelativeLayout comme racine du fichier de mise en page de votre boîte de dialog.

J’ai fini par remplacer Fragment.onResume() et récupérer les atsortingbuts de la boîte de dialog sous-jacente, puis définir les parameters width / height. Je définis la hauteur / largeur de disposition la plus externe sur match_parent . Notez que ce code semble également respecter les marges que j’ai définies dans la présentation XML.

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

J’ai un DialogFragment de taille fixe définissant ce qui suit dans la structure principale XML (LinearLayout dans mon cas):

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

La seule chose qui a fonctionné dans mon cas était la solution indiquée ici: http://adilatwork.blogspot.mx/2012/11/android-dialogfragment-dialog-sizing.html

Extrait du blog d’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 } 

Une façon de contrôler la largeur et la hauteur de votre DialogFragment est de vous assurer que sa boîte de dialog respecte la largeur et la hauteur de votre vue si leur valeur est WRAP_CONTENT .

Utiliser ThemeOverlay.AppCompat.Dialog

Un moyen simple d’y parvenir consiste à utiliser le style ThemeOverlay.AppCompat.Dialog inclus dans la bibliothèque de support Android.

DialogFragment avec 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 avec AlertDialog ( DialogFragment : 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(); } 

Vous pouvez également définir ThemeOverlay.AppCompat.Dialog comme thème par défaut lors de la création de vos boîtes de dialog, en l’ajoutant au thème XML de votre application.
Attention, de nombreuses boîtes de dialog ont besoin de la largeur minimale par défaut.

   

DialogFragment avec Dialog , utilisant 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 avec AlertDialog , utilisant android:alertDialogTheme ou alertDialogTheme (avertissement: 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(); } 

Prime

Sur les anciennes API Android, les Dialog semblent avoir des problèmes de largeur, en raison de leur titre (même si vous n’en définissez pas un).
Si vous ne voulez pas utiliser le style ThemeOverlay.AppCompat.Dialog et que votre Dialog n’a pas besoin d’un titre (ou d’un titre personnalisé), vous pouvez vouloir le désactiver:

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

Réponse obsolète, ne fonctionnera pas dans la plupart des cas

J’essayais de faire en sorte que la boîte de dialog respecte la largeur et la hauteur de ma mise en page, sans spécifier de taille fixe par programmation.

J’ai pensé que android:windowMinWidthMinor et android:windowMinWidthMajor étaient à l’origine du problème. Même s’ils n’étaient pas inclus dans le thème de mon Activity ou de mon Dialog , ils étaient toujours appliqués au thème de l’ Activity .

J’ai proposé trois solutions possibles.

Solution 1: créez un thème de boîte de dialog personnalisé et utilisez-le lors de la création de la boîte de dialog dans le DialogFragment .

  
 @Override public Dialog onCreateDialog(Bundle savedInstanceState) { return new Dialog(getActivity(), R.style.Theme_Material_Light_Dialog_NoMinWidth); } 

Solution 2: créez un thème personnalisé à utiliser dans un ContextThemeWrapper qui servira de Context à la boîte de dialog. Utilisez cette android:dialogTheme si vous ne souhaitez pas créer un thème de dialog personnalisé (par exemple, lorsque vous souhaitez utiliser le thème spécifié par android:dialogTheme ).

  
 @Override public Dialog onCreateDialog(Bundle savedInstanceState) { return new Dialog(new ContextThemeWrapper(getActivity(), R.style.Theme_Window_NoMinWidth), getTheme()); } 

Solution 3 (avec un AlertDialog ): appliquez android:windowMinWidthMinor et android:windowMinWidthMajor dans le ContextThemeWrapper créé par AlertDialog$Builder .

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

Gotcha # 13: DialogFragment page de DialogFragment

C’est une sorte d’esprit vraiment engourdissant.

Lors de la création d’un DialogFragment , vous pouvez choisir de remplacer onCreateView (qui transmet un ViewGroup pour attacher votre présentation .xml à) ou onCreateDialog , ce qui n’est pas le cas.

Vous ne devez pas ignorer les deux méthodes, car vous risquez de confondre Android avec le moment ou la disposition de votre boîte de dialog a été gonflée! WTF?

Le choix de remplacer OnCreateDialog ou OnCreateView dépend de la manière dont vous souhaitez utiliser la boîte de dialog.

  • Si vous lancez la boîte de dialog dans une fenêtre (le comportement normal), vous devez remplacer OnCreateDialog .
  • Si vous avez l’intention d’incorporer le fragment de dialog dans une présentation d’interface utilisateur existante (FAR moins courante), vous devez alors remplacer OnCreateView .

C’est peut-être la pire chose au monde.

onCreateDialog Insanity

Donc, vous onCreateDialog dans votre DialogFragment pour créer une instance personnalisée de AlertDialog à afficher dans une fenêtre. Cool. Mais souvenez-vous, onCreateDialog ne reçoit aucun ViewGroup pour attacher votre mise en page .xml personnalisée. Pas de problème, vous passez simplement null à la méthode de inflate .

Que la folie commence.

Lorsque vous remplacez onCreateDialog , Android COMPLETELY IGNORE plusieurs atsortingbuts du nœud racine de la mise en page .xml que vous gonflez. Cela inclut, mais n’est probablement pas limité à:

  • background_color
  • layout_gravity
  • layout_width
  • layout_height

C’est presque comique, car vous devez définir layout_width et layout_height de layout_height .xml Layout ou Android Studio vous donnera un joli petit badge rouge de honte.

Juste le mot DialogFragment me donne envie de vomir. Je pourrais écrire un roman rempli de pièges Android et de snafus, mais celui-ci est l’un des plus intenses.

Pour revenir à la santé mentale, nous déclarons d’abord un style pour restaurer JUST les background_color et layout_gravity nous attendons:

  

Le style ci-dessus hérite du thème de base pour Dialogs (dans le thème AppCompat dans cet exemple).

Ensuite, nous appliquons le style par programmation pour rétablir les valeurs que Android vient de mettre de côté et pour restaurer l’aspect standard d’ 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 ssortingps b.getContext().getTheme().applyStyle(R.style.MyAlertDialog, true); b.setView(layout); return b.create(); } } 

Le code ci-dessus fera que votre AlertDialog ressemblera à nouveau à AlertDialog . Peut-être que c’est assez bon.

Mais attendez, il y a plus!

Si vous cherchez à définir une layout_width ou un layout_width layout_height pour votre AlertDialog quand il est affiché (très probable), alors devinez quoi, vous ne l’avez pas encore fait!

L’hilarité continue alors que vous réalisez que si vous essayez de définir un layout_width ou un layout_width spécifique dans votre nouveau style, Android l’ignorera complètement!

  

Pour définir une largeur ou une hauteur SPÉCIFIQUE de fenêtre, vous devez passer à une méthode complète et gérer LayoutParams :

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

Beaucoup de gens suivent le mauvais exemple d’Android, qui WindowManager.LayoutParams à WindowManager.LayoutParams en un WindowManager.LayoutParams plus général que ViewGroup.LayoutParams , pour ensuite ViewGroup.LayoutParams vers WindowManager.LayoutParams quelques lignes plus tard. Java efficace soit damné, ce casting inutile ne propose rien d’autre que de rendre le code encore plus difficile à déchiffrer.

Remarque: LayoutParamsLayoutParams répétitions de LayoutParams sur le SDK Android – un exemple parfait de conception radicalement médiocre.

En résumé

Pour DialogFragment s qui remplacent onCreateDialog :

  • Pour restaurer l’apparence standard de AlertDialog , créez un style qui définit background_color = transparent et layout_gravity = center et appliquez ce style dans onCreateDialog .
  • Pour définir un layout_width spécifique et / ou layout_height , faites-le par programmation dans onResume avec LayoutParams
  • Pour maintenir la santé mentale, essayez de ne pas penser au SDK Android.

Quand j’ai besoin de rendre le DialogFragment un peu plus large, je mets minWidth:

  

Je l’ai corrigé en définissant les parameters d’agencement de l’élément racine.

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

La dimension dans la disposition la plus externe ne fonctionne pas dans la boîte de dialog. Vous pouvez append une mise en page dans laquelle la dimension est définie sous la limite extérieure.

    

Voici un moyen de définir DialogFragment width / height en xml. Enveloppez simplement votre viewHierarchy dans un Framelayout (n’importe quelle disposition fonctionnera) avec un arrière-plan transparent.

Un arrière-plan transparent semble être un indicateur spécial, car il centre automatiquement l’enfant de frameLayout dans la fenêtre lorsque vous faites cela. Vous obtiendrez toujours l’écran plein écran derrière votre fragment, indiquant que votre fragment est l’élément actif.

 < ?xml version="1.0" encoding="utf-8"?>   ..... 

Vous pouvez utiliser le pourcentage pour la largeur.

  

J'ai utilisé Holo Theme pour cet exemple.

Je crée la boîte de dialog en utilisant AlertDialog.Builder, j’ai donc utilisé la réponse de Rodrigo dans un OnShowListener.

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

Travailler sur Android 6.0, a rencontré le même problème. AlertDialog par défaut la width prédéfinie définie dans le thème, quelle que soit la width réelle définie dans la racine de la vue personnalisée. J’ai pu le faire régler correctement en ajustant la width de loading_message TextView . Sans enquêter plus avant, il semble que le dimensionnement des éléments réels et la Layout structure racine autour de ceux-ci le font fonctionner comme prévu. Vous trouverez ci-dessous une disposition XML d’une boîte de dialog de chargement qui définit correctement la width de la boîte de dialog. Utilisation de cette bibliothèque pour l’animation.

     

Vous pouvez sous le code pour définir la largeur et la hauteur de la mise en page à partir de Java.

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

Dans mon cas, cela a été causé par align_parentBottom="true" donné à une vue dans un RelativeLayout . Suppression de tous les alignParentBottom et modification de toutes les dispositions en LinearLayouts verticales et résolution des problèmes.

Facile et solide:

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

C’est la solution la plus simple

La meilleure solution que j’ai trouvée consiste à remplacer onCreateDialog() au lieu de onCreateView() . setContentView () va définir les dimensions correctes de la fenêtre avant de gonfler. Cela supprime la nécessité de stocker / définir une dimension, une couleur d’arrière-plan, un style, etc. dans les fichiers de ressources et de les définir manuellement.

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

Définissez la disposition parent de la disposition de dialog personnalisée sur RelativeLayout , obtenez automatiquement la largeur et la hauteur communes.

  

L’une des solutions précédentes a presque fonctionné. J’ai essayé quelque chose de légèrement différent et j’ai fini par travailler pour moi.

(Assurez-vous de regarder sa solution) C’était sa solution. Cliquez ici. Cela fonctionnait sauf pour: builder.getContext (). GetTheme (). ApplyStyle (R.style.Theme_Window_NoMinWidth, true);

Je l’ai changé pour

  @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 dernière ligne est vraiment différente.

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

Pour obtenir une boîte de dialog couvrant la quasi-totalité des éboulis: définissez d’abord une classe 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; } } 

Ensuite, vous devez appeler le ScreenParamater avant votre méthode getDialog.getWindow (). SetLayout ()

 @Override public void onResume() { super.onResume(); ScreenParameters s = new ScreenParameters(); getDialog().getWindow().setLayout(s.Width , s.Height); }