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


173

Je spécifie la mise en page de mon DialogFragment dans un fichier de mise en page xml (appelons-le layout_mydialogfragment.xml), et ses attributs layout_widthet en layout_heightparticulier (pour être 100dpchacun, disons). Je gonfle ensuite cette mise en page dans la onCreateView(...)méthode de mon DialogFragment comme suit:

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

Malheureusement, je trouve que lorsque ma boîte de dialogue (DialogFragment) apparaît, elle ne respecte pas le layout_widthet layout_heightspécifié dans son fichier de mise en page xml (et ma boîte de dialogue se rétrécit ou s'agrandit de manière variable en fonction du contenu). Quelqu'un sait si ou comment je peux faire en sorte que ma boîte de dialogue respecte le layout_widthet layout_heightspécifié dans son fichier de mise en page XML? Pour le moment, je dois à nouveau spécifier la largeur et la hauteur de ma boîte de dialogue dans la onResume()méthode de mon DialogFragment comme suit ...

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

... Et donc, de manière indésirable, ne pas oublier de modifier à l'avenir la largeur et la hauteur du dialogue à deux endroits.


2
Pensez à accepter la réponse de jpmcosta. Ce n'est pas un hack et cela résout le problème.
Bogdan Zurac

Réponses:


168

Si vous effectuez une conversion directement à partir des valeurs de ressources:

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

Spécifiez ensuite match_parent dans votre mise en page pour la boîte de dialogue:

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 dialogue.


3
Cette réponse ne fonctionne pas dans mon cas (pour DialogFragment). J'ai dû utiliser les paramètres FragmentLayout pour modifier la taille de la fenêtre d'affichage.
Rusfearuth

3
J'ai dû envelopper ma mise en page RelativeLayoutet cela m'a aidé. Merci beaucoup pour la solution - cela m'a fait gagner beaucoup de temps.
Johnny Doe

62
Cela fonctionne très bien pour moi (Android 4.0+), une fois que j'ai réalisé que cela devait être onResume(), non onCreateView(). (Ma disposition racine est RelativeLayout enveloppé dans un ScrollView.)
Jonik

14
Utile dans certains cas: utilisez toute la largeur de l'écran:int width = getResources().getDisplayMetrics().widthPixels
Jonik

6
+1 pour Jonik. -1 pour Richard. J'utilise toujours des fragments de support et je n'ai jamais pu faire fonctionner cela onCreateDialog(). Doit être dedans onResume().
MinceMan

146

J'ai fini par remplacer Fragment.onResume()et saisir les attributs de la boîte de dialogue sous-jacente, puis y définir les paramètres largeur / hauteur. J'ai défini la hauteur / largeur de la disposition la plus externe sur match_parent. Notez que ce code semble également respecter les marges que j'ai définies dans la mise en page 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);
}

2
Merci ! Ça marche pour moi ! De plus, c'est une manière élégante de le faire.
AntoineP

1
@jmaculate - Question rapide: lorsque vous lancez un casting (android.view.WindowManager.LayoutParams), depuis quoi le diffusez- vous? J'ai été perplexe lors du choix de l'importation correcte pour LayoutParamsapparaître dans les 3 premières lignes de la fonction. J'ai fini par choisir (android.view.WindowManager.LayoutParams). Est-ce censé être correct?
Dev-iL

@ Dev-iL getAttributes () renvoie un WindowManger.LayoutParams, mais dans mon cas, je le lance implicitement vers ViewGroup.LayoutParams car c'est tout ce dont j'ai besoin (Effective Java, Item 52) - je modifierai la question pour refléter cela
jmaculate

1
Si vous avez besoin de le lancer à nouveau android.view.WindowManager.LayoutParams, il est inutile d'utiliser les ViewGroup.LayoutParamstrois lignes ci-dessus ... Vous ne gagnez aucune flexibilité ici. Quoi qu'il en soit, merci pour cette bonne réponse!
Kevin Robatel

2
C'est la meilleure solution. Vous pouvez même utiliser une valeur spécifique de pixels avec MATCH_PARENT ou WRAP_CONTENT.
Koesh le

98

J'ai eu un DialogFragment de taille fixe définissant ce qui suit dans la mise en page principale XML (LinearLayout dans mon cas):

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

4
J'ai trouvé que j'avais besoin de midWidth et minHeight en Honeycomb - mais pas en ICS.
daveywc

1
Cela semble fonctionner à première vue, mais cela devrait probablement être évité. La vue continuera hors de l'écran en fonction de la largeur de l'appareil, donc si vous avez des boutons dans le coin inférieur droit, ils n'apparaîtront pas.
CodyEngel

La vue ne continue PAS hors de l'écran. Le système Android semble s'assurer que le DialogFragment reste dans les limites de la vue (avec une petite marge), même si ces limites sont plus petites que les valeurs minWidth et minHeight spécifiées.
Lensflare

51

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 de l'article du blog 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
}

Solution parfaite et très bien expliquée dans le blog.
varun bhardwaj

+1 getDialog().getWindow().setLayout(dialogWidth, dialogHeight); fonctionne parfaitement pour un DialogFragment. Mais je ne comprends pas le contrôle de sécurité. pourquoi devons-nous vérifier null?
tpk le

3
@ 2943 - simplement parce qu'il n'y a aucune garantie que le Dialog(un enfant du DialogFragment) sera disponible au moment où il est demandé. Il est possible qu'Android renvoie null lorsque nous appelons getDialog().
rmirabelle

@mirabelle si vous utilisez le rappel onStart de la boîte de dialogue comment la boîte de dialogue peut être nulle?
rommex le

49

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

En utilisant ThemeOverlay.AppCompat.Dialog

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

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

DialogFragmentavec AlertDialog(mise en garde:) 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.Dialogcomme thème par défaut lors de la création de vos boîtes de dialogue, en l'ajoutant au thème xml de votre application.
Faites attention, car de nombreuses boîtes de dialogue ont besoin de la largeur minimale par défaut pour bien paraître.

<!-- 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>

DialogFragmentavec Dialog, en 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;
}

DialogFragmentavec AlertDialog, en utilisant android:alertDialogThemeou alertDialogTheme(mise en garde:) 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 API Android plus anciennes, les Dialogs semblent avoir des problèmes de largeur, en raison de leur titre (même si vous n'en définissez pas).
Si vous ne souhaitez pas utiliser de ThemeOverlay.AppCompat.Dialogstyle et que vous Dialogn'avez pas besoin d'un titre (ou en a un personnalisé), vous pouvez 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 le dialogue respecte la largeur et la hauteur de ma mise en page, sans spécifier de taille fixe par programmation.

Je l'ai compris android:windowMinWidthMinoret android:windowMinWidthMajorcausais le problème. Même s'ils n'étaient pas inclus dans le thème de mon Activityou Dialog, ils étaient toujours appliqués au Activitythème, d'une manière ou d'une autre.

J'ai proposé trois solutions possibles.

Solution 1: créez un thème de boîte de dialogue personnalisé et utilisez-le lors de la création de la boîte de dialogue dans le 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);
}

Solution 2: créez un thème personnalisé à utiliser dans un ContextThemeWrapperqui servira de Contextdialogue. Utilisez cette option si vous ne souhaitez pas créer de thème de dialogue personnalisé (par exemple, lorsque vous souhaitez utiliser le thème spécifié par 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());
}

Solution 3 (avec un AlertDialog): appliquer android:windowMinWidthMinoret android:windowMinWidthMajorentrer dans le ContextThemeWrappercréé par le 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();
}

4
Je ne sais vraiment pas pourquoi ce n'est pas la réponse acceptée. C'est littéralement LA seule réponse qui fonctionne et qui n'est pas un hack (je parle surtout de votre 1ère solution).
Bogdan Zurac

1
malheureusement trouvé cela seulement après avoir passé une heure à trouver comment résoudre!
brainvision

La solution 3 me sauve la vie. Merci beaucoup
Simon

J'ai pu reproduire votre problème sur d'anciennes API Android. Ajout de quelques alternatives qui pourraient vous aider.
jpmcosta

La solution 1 a fonctionné pour moi. Je viens de l'utiliser Theme.MaterialComponents.Light.Dialogcomme parent et j'ai utilisé ce style dans le constructeur de MaterialAlertDialogBuilder. Je suis tombé sur votre réponse après une recherche d'une heure. Merci et bravo.
Shahood ul Hassan

39

Gotcha # 13: DialogFragmentMise en page

C'est vraiment un engourdissement de l'esprit.

Lors de la création d'un DialogFragment, vous pouvez choisir de remplacer onCreateView(qui transmet un ViewGrouppour attacher votre mise en page .xml) ou onCreateDialog, ce qui ne le fait pas.

Vous ne devez pas remplacer les deux méthodes, car vous risquez de confondre Android quant à savoir quand ou si la mise en page de votre boîte de dialogue a été gonflée! WTF?

Le choix de remplacer OnCreateDialogou OnCreateViewdépend de la manière dont vous comptez utiliser la boîte de dialogue.

  • Si vous lancez la boîte de dialogue dans une fenêtre (le comportement normal), vous êtes censé remplacer OnCreateDialog.
  • Si vous avez l'intention d'incorporer le fragment de boîte de dialogue dans une disposition d'interface utilisateur existante (FAR moins courante), vous êtes censé remplacer OnCreateView.

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

onCreateDialog Folie

Donc, vous remplacez onCreateDialogdans votre DialogFragmentpour créer une instance personnalisée de AlertDialogpour afficher dans une fenêtre. Cool. Mais rappelez-vous, onCreateDialogne reçoit pas ViewGrouppour attacher votre mise en page .xml personnalisée . Pas de problème, vous passez simplement nullà la inflateméthode.

Que la folie commence.

Lorsque vous remplacez onCreateDialog, Android IGNORE COMPLÈTEMENT plusieurs attributs 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 le layout_widthet layout_heightde CHAQUE mise en page .xml ou Android Studio vous giflera avec un joli petit badge rouge de la honte.

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

Pour revenir à la raison, d'abord, nous déclarons un style pour restaurer JUST the background_coloret layout_gravitynous attendons:

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

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

Ensuite, nous appliquons le style par programme pour remettre les valeurs qu'Android vient de jeter de côté et pour restaurer l' AlertDialogapparence standard :

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

Le code ci-dessus vous fera AlertDialogressembler à AlertDialognouveau. Peut-être que c'est assez bon.

Mais attendez, il y a plus!

Si vous cherchez à définir un SPÉCIFIQUE layout_width ou layout_heightpour votre AlertDialogquand il est affiché (très probable), alors devinez quoi, vous n'avez pas encore terminé!

L'hilarité continue lorsque vous réalisez que si vous essayez de définir un style spécifique layout_widthou layout_heightdans votre nouveau style sophistiqué, Android l'ignorera complètement aussi!:

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

Pour définir une largeur ou une hauteur de fenêtre SPÉCIFIQUE, vous devez vous diriger vers 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.getAttributes();
    params.width = 400;
    params.height = 400;
    window.setAttributes(params);
}

Beaucoup de gens suivent le mauvais exemple d'Android qui consiste à WindowManager.LayoutParamspasser au plus général ViewGroup.LayoutParams, seulement pour faire demi-tour et ViewGroup.LayoutParamsrevenir à WindowManager.LayoutParamsquelques lignes plus tard. Java efficace soit damné, ce casting inutile n'offre rien d'autre que de rendre le code encore plus difficile à déchiffrer.

Note latérale: Il y a VINGT répétitions LayoutParamsdans le SDK Android - un exemple parfait de conception radicalement médiocre.

En résumé

Pour les DialogFragments qui remplacent onCreateDialog:

  • Pour restaurer l' AlertDialogaspect et la convivialité standard , créez un style qui définit background_color= transparentet layout_gravity= centeret appliquez ce style dans onCreateDialog.
  • Pour définir un layout_widthet / ou spécifique layout_height, faites-le par programme onResumeavecLayoutParams
  • Pour maintenir la santé mentale, essayez de ne pas penser au SDK Android.

13
La lecture de cette réponse me donne envie de pleurer.
Bassinator

3
Mec, tu as décrit exactement ce que je vis en ce moment.
Mert Gülsoy

2
Android est de la merde. Je te sens frère. besoin d'un contexte pour tout, processus d'application tue, manque de bibliothèques de support pour certaines choses, la liste est
longue

1
@rmirabelle - cette réponse aide en fait, vous pouvez en fait écrire un blog moyen et peut être utile pour beaucoup. Dans mon cas, j'utilise la disposition de contrainte et DialogFragment, donc avec était ignoré dans Android 9, sous Android 9, cela fonctionne bien. J'ai ajouté - "android: windowMinWidthMajor," android: windowMinWidthMinor "avec style et cela a commencé à fonctionner correctement.
Rahul


14

Quand j'ai besoin d'élargir un peu le DialogFragment, je règle minWidth:

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

1
Meilleure solution à mon avis!
Fabian Knapp

Et si vous voulez le rendre plus étroit?
Daniel

8

Je ne vois pas une raison impérieuse de passer outre onResumeou onStartde définir la largeur et la hauteur du Windowsein de DialogFragmentl » Dialog- ces méthodes du cycle de vie particulier peuvent s'appelé exécuter de façon répétée et sans nécessité que le redimensionnement code plus d'une fois en raison de choses comme la commutation de plusieurs fenêtres, semi- finition puis mise au premier plan de l'application, et ainsi de suite. Les conséquences de cette répétition sont assez insignifiantes, mais pourquoi se contenter de cela?

Définir la largeur / hauteur à la place dans une onActivityCreated()méthode remplacée sera une amélioration car cette méthode n'est appelée de manière réaliste qu'une seule fois par instance de votre DialogFragment. Par exemple:

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

Ci-dessus, je viens de définir la largeur match_parentindépendamment de l'orientation de l'appareil. Si vous voulez que votre boîte de dialogue de paysage ne soit pas aussi large, vous pouvez vérifier si getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAITau préalable.


6

La cote dans la disposition la plus externe ne fonctionne pas dans la boîte de dialogue. Vous pouvez ajouter une mise en page où la dimension définie sous la plus extérieure.

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


5

Je l'ai corrigé en définissant les paramètres de disposition de l'élément racine.

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

5

Voici un moyen de définir la largeur / hauteur de DialogFragment en xml. Enveloppez simplement votre viewHierarchy dans un Framelayout (n'importe quelle mise en page fonctionnera) avec un fond 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'assombrissement en plein écran derrière votre fragment, indiquant que votre fragment est l'élément actif.

<?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">

      .....

Je vais essayer cela car si cela fonctionne de manière cohérente, c'est une approche VASTEMENT supérieure pour coder une partie de la mise en page en XML et une partie de celle-ci dans le code. Merci
rmirabelle

J'aime l'idée de cette approche, mais lorsqu'elle est testée, elle donne une disposition différente de celle du simple changement de hauteur et de largeur par programme. Par exemple, la largeur totale est réduite de force à la largeur maximale offerte par un AlertDialog (probablement à cause des styles Android). Lorsque je viens de définir w et h via le code, le style AlertDialog est remplacé. Cela peut cependant répondre à de nombreux besoins et c'est une bonne idée. Vive le pire SDK de l'histoire.
rmirabelle

A très bien fonctionné pour onCreateView, jusqu'à ce que je veuille changer la largeur intérieure en match_parent ...
tudor

5

Voici la version 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
    }

4

Vous pouvez utiliser le pourcentage pour la largeur.

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

J'ai utilisé Holo Theme pour cet exemple.


3

Vous pouvez ci-dessous 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().getAttributes();

WMLP.gravity = Gravity.TOP;
WMLP.y = mActionBarHeight;
WMLP.x = getResources().getDimensionPixelSize(R.dimen.unknown_image_width);

alertDialog.getWindow().setAttributes(WMLP);
alertDialog.show();

2

Je crée la boîte de dialogue en utilisant AlertDialog.Builder donc j'ai utilisé la réponse de Rodrigo dans 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));
            }

        });

(Principalement pour les futurs lecteurs :) Voir le commentaire de Snicolasdans la discussion de " DialogFragmentvs AlertDialog" dans stackoverflow.com/a/7979823/3372061 .
Dev-iL

2

Travailler sur Android 6.0, a rencontré le même problème. AlertDialogserait défini par défaut sur l' widthensemble prédéfini dans le thème, quel que soit l' widthensemble réel dans la racine de la vue personnalisée Layout. J'ai pu le faire régler correctement en ajustant widthle loading_message TextView. Sans chercher plus loin, il semble que le dimensionnement des éléments réels et le fait que la racine les Layoutentoure le fasse fonctionner comme prévu. Voici une présentation XML d'une boîte de dialogue de chargement qui définit widthcorrectement la boîte de dialogue. Utilisation de cette bibliothèque pour l'animation.

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

2

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

2

Dans mon cas, DialogFragmentoccupé la taille de l'activité complète comme un Fragment. Le DialogFragmentétait basé sur la mise en page XML, non AlertDialog. Mon erreur a été d'ajouter le fragment de dialogue à FragmentManagerun fragment habituel:

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

Au lieu de cela, j'ai besoin showdu fragment de dialogue:

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

Après quelques modifications (j'ai ViewPager2dans la mise en page), le fragment de dialogue est devenu trop étroit:

entrez la description de l'image ici

J'ai utilisé la solution de N1hk :

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

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

Maintenant, il a défini la largeur et la hauteur, et non la taille totale de l'activité.

Je veux dire sur onCreateViewetonCreateDialog . Si vous disposez d'un fragment de dialogue basé sur la mise en page, vous pouvez utiliser l'une de ces 2 méthodes.

1) Si vous utilisez onCreateView, vous devez utiliseronActivityCreated pour définir la largeur.

2) Si vous utilisez à la onCreateDialogplace de onCreateView, vous pouvez y définir des paramètres. onActivityCreatedne sera pas nécessaire.

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
}

Vous avez sauvé ma journée, la définition de la largeur dans onActivityCreated a fonctionné pour moi.
Hagar Magdy

@ManishKumarSharma, bonne chance!
CoolMind le

1

Dans mon cas, cela a été causé par align_parentBottom="true"une vue à l'intérieur d'un RelativeLayout. Suppression de tous les alignParentBottom et modification de toutes les mises en page en LinearLayouts verticales et le problème a disparu.


1

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

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

Cela a fonctionné pour moi. Je voulais utiliser un ConstraintLayout pour disposer les contrôles dans ma boîte de dialogue, j'ai donc utilisé un RelativeLayout pour la disposition racine, puis mis un ConstraintLayout directement à l'intérieur. Cela m'a donné une boîte de dialogue de taille normale. Quand j'ai mis le ConstraintLayout en tant que racine sans rien changer d'autre, la largeur de la boîte de dialogue a implosé à pas très large!
coupe

1

L'une des solutions précédentes a presque fonctionné. J'ai essayé quelque chose de légèrement différent et cela a fonctionné pour moi.

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

Je l'ai changé en

 @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 ce qui est vraiment différent.


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

0

C'est la solution la plus simple

La meilleure solution que j'ai trouvée est de remplacer onCreateDialog()au lieu de onCreateView(). setContentView () définira les dimensions correctes de la fenêtre avant de gonfler. Cela supprime le besoin 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;
}

0

Ajoutez à votre 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();
}

0

Cela fonctionnera parfaitement.

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

C'est à peu près ce que dit la réponse acceptée d'il y a plus de 3 ans.
Adil Hussain le

-4

Pour obtenir une boîte de dialogue qui couvre presque tout le scree: 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);
}
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.