Come impostare la larghezza e l'altezza di DialogFragment?


173

Specifico il layout del mio DialogFragment in un file di layout xml (chiamiamolo layout_mydialogfragment.xml), e in particolare i suoi attributi layout_widthe layout_height(per esempio, 100dpciascuno). Quindi gonfio questo layout nel onCreateView(...)metodo di DialogFragment come segue:

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

Sfortunatamente, trovo che quando appare la mia finestra di dialogo (DialogFragment), non rispetta layout_widthe layout_heightspecificato nel suo file di layout xml (e la mia finestra di dialogo si restringe o si espande in modo variabile a seconda del contenuto). Qualcuno sa se o come posso ottenere la mia finestra di dialogo per rispettare layout_widthe layout_heightspecificato nel suo file di layout XML? Al momento devo specificare nuovamente la larghezza e l'altezza della mia finestra di dialogo nel onResume()metodo di DialogFragment come segue ...

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

... E quindi, indesiderabilmente, bisogna ricordare di apportare eventuali modifiche future alla larghezza e all'altezza della finestra di dialogo in due punti.


2
Prendi in considerazione l'idea di accettare la risposta di jpmcosta. Non è un trucco e risolve effettivamente il problema.
Bogdan Zurac,

Risposte:


168

Se converti direttamente dai valori delle risorse:

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

Quindi specifica match_parent nel layout per la finestra di dialogo:

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

Devi solo preoccuparti di un posto (posizionalo nel tuo DialogFragment#onResume). Non è perfetto, ma almeno funziona per avere un RelativeLayout come radice del file di layout della finestra di dialogo.


3
Questa risposta non funziona nel mio caso (per DialogFragment). Ho dovuto usare i parametri FragmentLayout per cambiare la dimensione della finestra di visualizzazione.
Rusfearuth,

3
Ho dovuto avvolgere il mio layout RelativeLayoute mi ha aiutato. Mille grazie per la soluzione: mi ha fatto risparmiare un sacco di tempo.
Johnny Doe,

62
Questo funziona alla grande per me (Android 4.0+), una volta che ho capito che doveva esserlo onResume(), no onCreateView(). (Il mio layout di root è RelativeLayout racchiuso in uno ScrollView.)
Jonik,

14
Utile in alcuni casi: utilizzare l'intera larghezza dello schermo:int width = getResources().getDisplayMetrics().widthPixels
Jonik,

6
+1 per Jonik. -1 per Richard. Uso sempre frammenti di supporto e non sono mai stato in grado di farlo funzionare onCreateDialog(). Deve essere dentro onResume().
MinceMan,

146

Ho finito per scavalcare Fragment.onResume()e afferrare gli attributi dalla finestra di dialogo sottostante, quindi impostare parametri di larghezza / altezza lì. Ho impostato l'altezza / larghezza del layout più esterno su match_parent. Si noti che questo codice sembra rispettare anche i margini che ho definito nel layout 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
Grazie ! Per me funziona ! Inoltre questo è un modo elegante per farlo.
Antoine,

1
@jmaculate - Domanda veloce: quando stai lanciando (android.view.WindowManager.LayoutParams), da che cosa stai lanciando? Sono rimasto perplesso nella scelta dell'importazione corretta per LayoutParamsapparire nelle prime 3 righe della funzione. Ho finito per scegliere (android.view.WindowManager.LayoutParams). Questo dovrebbe essere corretto?
Dev-iL,

@ Dev-iL getAttributes () restituisce un WindowManger.LayoutParams, ma nel mio caso lo ho implicitamente lanciato su ViewGroup.LayoutParams perché è tutto ciò di cui ho bisogno (Effective Java, Item 52)
Modificherò

1
Se devi lanciarlo nuovamente su android.view.WindowManager.LayoutParams, è inutile usare ViewGroup.LayoutParamstre righe sopra ... Non ottieni alcuna flessibilità qui. Comunque, grazie per questa buona risposta!
Kevin Robatel,

2
Questa è la soluzione migliore Puoi persino utilizzare un valore specifico di pixel insieme a MATCH_PARENT o WRAP_CONTENT.
Koesh,

98

Ho ottenuto un DialogFragment a dimensione fissa che definisce quanto segue nel layout principale XML (LinearLayout nel mio caso):

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

4
Ho scoperto che avevo bisogno di midWidth e minHeight in Honeycomb, ma non in ICS.
daveywc,

1
Questo sembra funzionare a prima vista, ma probabilmente dovrebbe essere evitato. La vista continuerà fuori dallo schermo a seconda della larghezza del dispositivo, quindi se hai dei pulsanti nell'angolo in basso a destra non verranno visualizzati.
CodyEngel,

La vista NON continua fuori dallo schermo. Il sistema Android sembra assicurarsi che DialogFragment rimanga all'interno dei limiti della vista (con un piccolo margine), anche se questi limiti sono più piccoli di minWidth e minHeight specificati.
Lensflare,

51

L'unica cosa che ha funzionato nel mio caso è stata la soluzione indicata qui: http://adilatwork.blogspot.mx/2012/11/android-dialogfragment-dialog-sizing.html

Snippet dal post del 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
}

Soluzione perfetta e molto ben spiegata nel blog.
varun bhardwaj,

+1 getDialog().getWindow().setLayout(dialogWidth, dialogHeight); funziona perfettamente per un DialogFragment. Ma non capisco il controllo di sicurezza. perché dobbiamo controllare null?
TP

3
@ 2943 - semplicemente perché non esiste alcuna garanzia che il Dialog(figlio del DialogFragment) sarà disponibile al momento della richiesta. È possibile che Android restituisca null quando chiamiamo getDialog().
rmirabelle,

@mirabelle se stai eseguendo il callback onStart della finestra di dialogo come può essere nulla la finestra di dialogo?
rommex,

49

Un modo per controllare la DialogFragmentlarghezza e l'altezza della tua è quello di assicurarti che la sua finestra di dialogo rispetti la larghezza e l'altezza della tua vista se il loro valore è WRAP_CONTENT.

utilizzando ThemeOverlay.AppCompat.Dialog

Un modo semplice per raggiungere questo obiettivo è utilizzare lo ThemeOverlay.AppCompat.Dialogstile incluso nella libreria di supporto 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(avvertenza:) 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();
}

Puoi anche impostare ThemeOverlay.AppCompat.Dialogcome tema predefinito durante la creazione delle finestre di dialogo, aggiungendolo al tema XML della tua app.
Fai attenzione, poiché molte finestre di dialogo hanno bisogno della larghezza minima predefinita per avere un bell'aspetto.

<!-- 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, avvalendosi di 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, usando android:alertDialogThemeo alertDialogTheme(avvertenza:) 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();
}

indennità

Sulle vecchie API Android, Dialogsembra che abbiano dei problemi di larghezza, a causa del loro titolo (anche se non ne hai impostato uno).
Se non vuoi usare lo ThemeOverlay.AppCompat.Dialogstile e Dialognon hai bisogno di un titolo (o ne hai uno personalizzato), potresti disabilitarlo:

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

Risposta obsoleta, nella maggior parte dei casi non funzionerà

Stavo cercando di fare in modo che la finestra di dialogo rispettasse la larghezza e l'altezza del mio layout, senza specificare una dimensione fissa programmaticamente.

L'ho capito android:windowMinWidthMinore stavo android:windowMinWidthMajorcausando il problema. Anche se non erano inclusi nel tema del mio Activityo , in qualche modo Dialogvenivano comunque applicati al Activitytema.

Ho trovato tre possibili soluzioni.

Soluzione 1: creare un tema di dialogo personalizzato e utilizzarlo durante la creazione della finestra di dialogo in 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);
}

Soluzione 2: creare un tema personalizzato da utilizzare in un ContextThemeWrapperche servirà come Contextper la finestra di dialogo. Utilizzare questo se non si desidera creare un tema di dialogo personalizzato (ad esempio, quando si desidera utilizzare il tema specificato da 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());
}

Soluzione 3 (con un AlertDialog): applicare android:windowMinWidthMinore android:windowMinWidthMajornel ContextThemeWrappercreato da 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
Non so davvero perché diavolo questa non sia la risposta accettata. Questa è letteralmente L'unica risposta che funziona e non è un trucco (sto parlando principalmente per la tua prima soluzione).
Bogdan Zurac,

1
purtroppo l'ho trovato solo dopo aver trascorso un'ora a capire come risolverlo!
brainvision

La soluzione 3 mi salva la vita. Grazie mille
Simon,

Sono stato in grado di riprodurre il tuo problema su API Android meno recenti. Aggiunte alcune alternative che potrebbero aiutarti.
jpmcosta,

La soluzione 1 ha funzionato per me. ho appena usato Theme.MaterialComponents.Light.Dialogcome genitore e ho usato questo stile nel costruttore di MaterialAlertDialogBuilder. Inciampato sulla tua risposta dopo una ricerca di 1 ora. Grazie e pollice in alto.
Shahood ul Hassan,

39

Gotcha # 13: DialogFragmentLayouts

È una specie di intorpidimento mentale davvero.

Quando si crea un DialogFragment, è possibile scegliere di eseguire l'override onCreateView(che passa a ViewGroupa cui allegare il layout .xml) oppure onCreateDialog, in caso contrario.

Non devi ignorare entrambi i metodi, perché molto probabilmente confonderai Android su quando o se il layout della tua finestra di dialogo è stato gonfiato! WTF?

La scelta se eseguire l'override OnCreateDialogo OnCreateViewdipende da come si intende utilizzare la finestra di dialogo.

  • Se avvierai la finestra di dialogo in una finestra (il comportamento normale), devi ignorare OnCreateDialog.
  • Se si intende incorporare il frammento della finestra di dialogo all'interno di un layout UI esistente (FAR meno comune), è necessario eseguire l'override OnCreateView .

Questa è forse la cosa peggiore al mondo.

onCreateDialog Follia

Quindi, stai scavalcando il onCreateDialogtuo DialogFragmentper creare un'istanza personalizzata AlertDialogda visualizzare in una finestra. Freddo. Ma ricordate, onCreateDialognon riceve ViewGroupper fissare la vostra abitudine XML di layout a . Nessun problema, passi semplicemente nullalinflate metodo.

Che la follia abbia inizio.

Quando esegui l' override onCreateDialog, Android IGNORA COMPLETAMENTE diversi attributi del nodo radice del layout .xml che gonfia. Questo include, ma probabilmente non è limitato a:

  • background_color
  • layout_gravity
  • layout_width
  • layout_height

Questo è quasi comico, poiché ti viene richiesto di impostare layout_widthe layout_heightdi OGNI formato .xml o Android Studio ti schiaffeggerà con un bel distintivo rosso di vergogna.

Solo la parola DialogFragment mi fa venire voglia di vomitare. Potrei scrivere un romanzo pieno di gotchas e snafus Android, ma questo è uno dei più mostruosi.

Per tornare alla sanità mentale, in primo luogo, dichiariamo uno stile per ripristinare SOLO il background_colore layout_gravityci aspettiamo:

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

Lo stile sopra eredita dal tema di base per le finestre di dialogo (nel AppCompattema in questo esempio).

Successivamente, applichiamo lo stile a livello di codice per ripristinare i valori che Android ha appena scartato e per ripristinare l' AlertDialogaspetto 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();
    }
}

Il codice sopra ti farà AlertDialogsembrare di AlertDialognuovo un . Forse è abbastanza buono.

Ma aspetta, c'è di più!

Se stai cercando di impostare un SPECIFICO layout_width o layout_heightper il tuoAlertDialog quando viene mostrato (molto probabilmente), allora indovina un po ', non hai ancora finito!

L'ilarità continua quando ti rendi conto che se provi a impostare uno stile specifico layout_widtho layout_heightnel tuo nuovo stile, anche Android lo ignorerà completamente !:

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

Per impostare una larghezza o un'altezza SPECIFICA della finestra, si arriva a un metodo "nuther" completo e si occupa di 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);
}

Molte persone seguono il cattivo esempio di Android di lanciare WindowManager.LayoutParamsverso il più generale ViewGroup.LayoutParams, solo per girare a destra e ViewGroup.LayoutParamstornare indietro di WindowManager.LayoutParamsalcune righe in seguito. Malgrado l'effettiva Java, quel casting inutile non offre NIENTE oltre a rendere il codice ancora più difficile da decifrare.

Nota a margine: ci sono alcune VENTRE ripetizioni in LayoutParamstutto l'SDK di Android - un esempio perfetto di design radicalmente scadente.

In sintesi

Per quelli DialogFragmentche hanno la precedenza onCreateDialog:

  • Per ripristinare l' AlertDialogaspetto standard , crea uno stile che imposta background_color= transparente layout_gravity= centere applica quello stile onCreateDialog.
  • Per impostare uno specifico layout_widthe / o layout_height, farlo programmaticamente onResumeconLayoutParams
  • Per mantenere la sanità mentale, cerca di non pensare all'SDK di Android.

13
Leggere questa risposta mi fa venire voglia di piangere.
Bassinator

3
Amico, hai descritto esattamente quello che sto vivendo in questo momento.
Mert Gülsoy,

2
Android è una merda. Ti sento fratello. che necessita di un contesto per tutto, il processo delle app uccide, la mancanza di librerie di supporto per alcune cose, l'elenco continua
DennisVA

1
@rmirabelle: questa risposta aiuta davvero, puoi effettivamente scrivere un blog medio e può essere utile per molti. Nel mio caso sto usando il layout dei vincoli e DialogFragment, quindi con Ignora in Android 9, sotto Android 9 funziona bene. Ho aggiunto - "android: windowMinWidthMajor", "android: windowMinWidthMinor" con stile e ha iniziato a funzionare bene.
Rahul,


14

Quando devo rendere DialogFragment un po 'più ampio, sto impostando minWidth:

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

1
La migliore soluzione secondo me!
Fabian Knapp,

cosa succede se vuoi restringerlo?
Daniel

8

Non vedo un motivo valido per escludere onResumeo onStartper impostare la larghezza e l'altezza del Windowraggio DialogFragments' Dialog- questi particolari metodi del ciclo di vita possono ottenere chiamato ripetutamente e inutilmente eseguire tale ridimensionamento codice più di una volta a causa di cose come commutazione multi finestra, backgrounding quindi in primo piano l'app e così via. Le conseguenze di quella ripetizione sono abbastanza banali, ma perché accontentarsi di quello?

L'impostazione della larghezza / altezza invece all'interno di un onActivityCreated()metodo ignorato sarà un miglioramento perché questo metodo viene realisticamente chiamato solo una volta per istanza del tuo DialogFragment. Per esempio:

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

Sopra ho appena impostato la larghezza in modo che sia match_parentindipendente dall'orientamento del dispositivo. Se desideri che la finestra di dialogo orizzontale non sia così ampia, puoi verificare se in getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAITanticipo.


6

La dimensione nel layout più esterno non funziona nella finestra di dialogo. È possibile aggiungere un layout in cui impostare la dimensione sotto la più esterna.

<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

L'ho risolto impostando i parametri di layout dell'elemento radice.

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

5

Ecco un modo per impostare la larghezza / altezza di DialogFragment in xml. Basta avvolgere la vista Gerarchia in un Framelayout (qualsiasi layout funzionerà) con uno sfondo trasparente.

Uno sfondo trasparente sembra essere una bandiera speciale, perché centra automaticamente il figlio del frameLayout nella finestra quando lo fai. Otterrai comunque lo schermo intero che si oscura dietro il tuo frammento, indicando che il tuo frammento è l'elemento attivo.

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

      .....

Proverò questo perché, se funziona in modo coerente, è un approccio VASTAMENTE superiore alla codifica di una parte del layout in XML e di una parte in codice. Grazie
rmirabelle il

Mi piace l'idea di questo approccio, ma quando testato, produce un layout diverso rispetto alla semplice modifica di altezza e larghezza a livello di codice. Ad esempio, la larghezza complessiva viene forzatamente ridotta alla larghezza massima offerta da un AlertDialog (presumibilmente a causa degli stili Android). Quando ho appena impostato w e h tramite codice, lo stile AlertDialog viene annullato. Questo può soddisfare molte esigenze ed è una buona idea. Lunga vita al peggior SDK della storia.
rmirabelle,

Ha funzionato alla grande con onCreateView, fino a quando non volevo cambiare la larghezza interna in match_parent ...
tudor

5

Ecco la versione di 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

Puoi usare la percentuale per la larghezza.

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

Ho usato il tema Holo per questo esempio.


3

Puoi sotto il codice per impostare la larghezza e l'altezza del layout da 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

Creo la finestra di dialogo usando AlertDialog.Builder così ho usato la risposta di Rodrigo all'interno di 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));
            }

        });

(Principalmente per i futuri lettori :) Vedi il commento Snicolasnella discussione di " DialogFragmentvs AlertDialog" in stackoverflow.com/a/7979823/3372061 .
Dev-iL,

2

Lavorando su Android 6.0, si è verificato lo stesso problema. AlertDialogsarebbe widthimpostato di default sul set predefinito nel tema indipendentemente dal widthset effettivo nella radice della vista personalizzata Layout. Sono stato in grado di farlo impostare correttamente regolando widthil loading_message TextView. Senza ulteriori approfondimenti, sembra che il dimensionamento degli elementi effettivi e il Layoutloro avvolgimento della radice lo faccia funzionare come previsto. Di seguito è riportato un layout XML di una finestra di dialogo di caricamento che imposta widthcorrettamente la finestra di dialogo. Utilizzando questa libreria per l'animazione.

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

2

Nel mio caso ho DialogFragmentoccupato la dimensione dell'attività completa come a Fragment. Si DialogFragmentbasava sul layout XML, no AlertDialog. Il mio errore è stato l'aggiunta del frammento di dialogo FragmentManagercome un normale frammento:

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

Invece ho bisogno showdel frammento del dialogo:

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

Dopo alcune modifiche (ho ViewPager2nel layout) il frammento della finestra di dialogo è diventato troppo stretto:

inserisci qui la descrizione dell'immagine

Ho usato la soluzione di N1hk :

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

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

Ora ha definito la larghezza e l'altezza, non la dimensione dell'attività completa.

Voglio dire di onCreateViewe onCreateDialog. Se si dispone di un frammento della finestra di dialogo basato sul layout, è possibile utilizzare uno di questi 2 metodi.

1) Se si utilizza onCreateView, è necessario utilizzare onActivityCreatedper impostare la larghezza.

2) Se si utilizza onCreateDialoginvece di onCreateView, è possibile impostare i parametri lì. onActivityCreatednon sarà necessario.

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
}

Mi hai salvato la giornata, impostando la larghezza in onActivityCreated ha funzionato per me.
Hagar Magdy,

@ManishKumarSharma, buona fortuna!
CoolMind

1

Nel mio caso è stato causato dalla align_parentBottom="true"vista all'interno di a RelativeLayout. Rimossi tutti i alignParentBottom e cambiato tutti i layout in LinearLayout verticali e il problema è andato.


1

Impostare il layout padre del layout della finestra di dialogo personalizzata su RelativeLayout , ottenere automaticamente larghezza e altezza comuni.

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

Questo ha funzionato per me. Volevo usare un ConstraintLayout per disporre i controlli nella mia finestra di dialogo, quindi ho usato un RelativeLayout per il layout di root e quindi ho inserito un ConstraintLayout direttamente al suo interno. Questo mi ha dato un dialogo di dimensioni normali. Quando inserisco ConstraintLayout come root senza cambiare nient'altro, la larghezza della finestra di dialogo implode a non molto ampia!
tagliafoglie

1

Una delle soluzioni precedenti ha quasi funzionato. Ho provato qualcosa di leggermente diverso e alla fine ha funzionato per me.

(Assicurati di guardare la sua soluzione) Questa era la sua soluzione. Fai clic qui Ha funzionato tranne: builder.getContext (). GetTheme (). ApplyStyle (R.style.Theme_Window_NoMinWidth, true);

L'ho cambiato in

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

L'ultima riga è davvero diversa.


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

Questa è la soluzione più semplice

La migliore soluzione che ho trovato è quella di sostituire onCreateDialog()invece di onCreateView(). setContentView () imposterà le dimensioni corrette della finestra prima di gonfiare. Elimina la necessità di memorizzare / impostare una dimensione, il colore di sfondo, lo stile, ecc. Nei file di risorse e impostarli 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;
}

0

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

Funzionerà perfettamente.

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

Questo è praticamente ciò che dice la risposta accettata da 3+ anni fa.
Adil Hussain,

-4

Per ottenere una finestra di dialogo che copre quasi l'intero ghiaione: per prima cosa definire una 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;
    }
}

Quindi devi chiamare ScreenParamater prima del tuo metodo getDialog.getWindow (). SetLayout ()

@Override
public void onResume()
{
    super.onResume();
    ScreenParameters s = new ScreenParameters();
    getDialog().getWindow().setLayout(s.Width , s.Height);
}
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.