Como definir a largura e a altura do DialogFragment?


173

Eu especifico o layout do meu DialogFragment em um arquivo de layout xml (vamos chamá-lo layout_mydialogfragment.xml), e seus atributos layout_widthe layout_heightparticularmente ( 100dpcada um, digamos). Em seguida, inflo esse layout no onCreateView(...)método do meu DialogFragment da seguinte maneira:

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

Infelizmente, acho que quando minha caixa de diálogo (DialogFragment) aparece, ela não respeita layout_widthe é layout_heightespecificada em seu arquivo de layout xml (e minha caixa de diálogo diminui ou se expande de maneira variável, dependendo do conteúdo). Alguém sabe se ou como posso fazer com que minha caixa de diálogo respeite layout_widthe layout_heightespecifique em seu arquivo de layout xml? No momento, estou precisando especificar a largura e a altura da minha caixa de diálogo novamente no onResume()método do meu DialogFragment da seguinte maneira ...

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

... E, portanto, indesejávelmente, lembre-se de fazer alterações futuras na largura e altura da caixa de diálogo em dois lugares.


2
Considere aceitar a resposta do jpmcosta. Não é um hack e realmente corrige o problema.
Bogdan Zurac 05/10

Respostas:


168

Se você converter diretamente dos valores dos recursos:

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

Em seguida, especifique match_parent no seu layout para a caixa de diálogo:

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

Você só precisa se preocupar com um lugar (coloque-o no seu DialogFragment#onResume). Não é perfeito, mas pelo menos funciona para ter um RelativeLayout como a raiz do arquivo de layout da sua caixa de diálogo.


3
Esta resposta não funciona no meu caso (para DialogFragment). Eu tive que usar parâmetros de FragmentLayout para alterar o tamanho da janela de exibição.
Rusfearuth 26/12/12

3
Eu tive que envolver meu layout RelativeLayoute isso me ajudou. Muito obrigado pela solução - isso me salvou muito tempo.
Johnny Doe

62
Isso funciona muito bem para mim (Android 4.0 ou superior), uma vez que percebi que isso deve acontecer onResume(), não onCreateView(). (Meu layout raiz é RelativeLayout envolto em um ScrollView.)
Jonik

14
Útil em alguns casos: use toda a largura da tela:int width = getResources().getDisplayMetrics().widthPixels
Jonik 27/02

6
+1 para Jonik. -1 para Richard. Eu sempre uso fragmentos de suporte e nunca consegui fazer isso funcionar onCreateDialog(). Precisa estar em onResume().
MinceMan

146

Acabei substituindo Fragment.onResume()e pegando os atributos da caixa de diálogo subjacente e definindo parâmetros de largura / altura lá. Defino a altura / largura do layout mais externo para match_parent. Observe que esse código parece respeitar também as margens que eu defini no 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
Obrigado ! Funciona para mim ! Além disso, esta é uma maneira elegante de fazê-lo.
AntoineP

1
@jmaculate - Pergunta rápida: quando você está lançando (android.view.WindowManager.LayoutParams), o que você está lançando? Fiquei intrigado ao escolher a importação correta para LayoutParamsaparecer nas três primeiras linhas da função. Acabou escolhendo (android.view.WindowManager.LayoutParams). Isso deveria estar correto?
Dev-iL

@ Dev-iL getAttributes () retorna um WindowManger.LayoutParams, mas no meu caso eu o implico implicitamente em ViewGroup.LayoutParams porque é tudo o que preciso (Java efetivo, item 52)
editarei

1
Se você precisar convertê-lo novamente android.view.WindowManager.LayoutParams, é inútil usar ViewGroup.LayoutParamstrês linhas acima ... Você não ganha flexibilidade aqui. Seja como for, obrigado por esta boa resposta!
Kevin Robatel

2
essa é a melhor solução. Você pode até usar um valor específico de pixels junto com MATCH_PARENT ou WRAP_CONTENT.
Koesh

98

Eu recebi um DialogFragment de tamanho fixo, definindo o seguinte no layout principal do XML (LinearLayout no meu caso):

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

4
Descobri que precisava da largura média e da altura mínima no favo de mel - mas não no ICS.
Davidwc

1
Isso parece funcionar à primeira vista, mas provavelmente deve ser evitado. A visualização continuará fora da tela, dependendo da largura do dispositivo, portanto, se você tiver botões no canto inferior direito, eles não aparecerão.
CodyEngel

A visualização NÃO continua fora da tela. O sistema Android parece garantir que o DialogFragment permaneça dentro dos limites da visualização (com uma pequena margem), mesmo que esses limites sejam menores que os minWidth e minHeight especificados.
Lensflare

51

A única coisa que funcionou no meu caso foi a solução apontada aqui: http://adilatwork.blogspot.mx/2012/11/android-dialogfragment-dialog-sizing.html

Snippet da postagem do blog da 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
}

Solução perfeita e muito bem explicada no blog.
precisa saber é o seguinte

O +1 getDialog().getWindow().setLayout(dialogWidth, dialogHeight); funciona perfeitamente para um DialogFragment. Mas eu não entendo a verificação de segurança. por que nós temos que verificar null?
tpk

3
@ 2943 - simplesmente porque não há garantia de que o Dialog(filho do DialogFragment) estará disponível no momento em que for solicitado. É possível que o Android retorne nulo quando ligarmos getDialog().
precisa saber é o seguinte

@mirabelle se você estiver usando o retorno de chamada onStart da caixa de diálogo como a caixa de diálogo pode ser nula?
Rommex

49

Uma maneira de controlar a DialogFragmentlargura e a altura da sua pessoa é garantir que a caixa de diálogo respeite a largura e a altura da visualização, se o valor for esse WRAP_CONTENT.

Usando ThemeOverlay.AppCompat.Dialog

Uma maneira simples de conseguir isso é usar o ThemeOverlay.AppCompat.Dialogestilo incluído na Biblioteca de Suporte do Android.

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

DialogFragmentcom AlertDialog(ressalva :) 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();
}

Você também pode definir ThemeOverlay.AppCompat.Dialogcomo tema padrão ao criar suas caixas de diálogo, adicionando-o ao tema xml do seu aplicativo.
Tenha cuidado, pois muitas caixas de diálogo precisam da largura mínima padrão para parecerem boas.

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

DialogFragmentcom Dialog, utilizando 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;
}

DialogFragmentcom AlertDialog, utilizando android:alertDialogThemeou alertDialogTheme(ressalva :) 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();
}

Bônus

Nas APIs mais antigas do Android, Dialogs parecem ter alguns problemas de largura devido ao título (mesmo se você não definir um).
Se você não deseja usar o ThemeOverlay.AppCompat.Dialogestilo e Dialognão precisa de um título (ou tem um personalizado), convém desativá-lo:

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

Resposta desatualizada, não funcionará na maioria dos casos

Eu estava tentando fazer com que a caixa de diálogo respeitasse a largura e a altura do meu layout, sem especificar um tamanho fixo programaticamente.

Eu percebi isso android:windowMinWidthMinore android:windowMinWidthMajorestava causando o problema. Mesmo que não tenham sido incluídos no tema do meu Activityor Dialog, ainda estavam sendo aplicados ao Activitytema, de alguma forma.

Eu vim com três soluções possíveis.

Solução 1: crie um tema de diálogo personalizado e use-o ao criar o diálogo no 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);
}

Solução 2: crie um tema personalizado para ser usado em um ContextThemeWrapperque servirá como Contextpara o diálogo. Use isso se você não desejar criar um tema de diálogo personalizado (por exemplo, quando desejar usar o 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());
}

Solução 3 (com um AlertDialog): aplicar android:windowMinWidthMinore criar android:windowMinWidthMajoro ContextThemeWrappercriado pelo 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
Realmente não sei por que diabos essa não é a resposta aceita. Esta é literalmente a única resposta que funciona e não é um hack (estou falando principalmente da sua primeira solução).
Bogdan Zurac

1
infelizmente, só encontrei isso depois de passar uma hora imaginando como resolver!
brainvision

Solução 3 salva minha vida. Muito obrigado
Simon

Consegui reproduzir seu problema em APIs Android mais antigas. Adicionadas algumas alternativas que podem ajudá-lo.
Jpmcosta

Solução 1 funcionou para mim. Eu apenas usei Theme.MaterialComponents.Light.Dialogcomo pai e usei esse estilo no construtor de MaterialAlertDialogBuilder. Encontrei sua resposta após uma pesquisa de 1 hora. Obrigado e polegares para cima.
Shahood ul Hassan

39

Pegadinha 13: DialogFragmentlayouts

É meio que entorpecente mesmo.

Ao criar um DialogFragment, você pode optar por substituir onCreateView(que passa por um ViewGrouppara anexar o layout .xml) ou onCreateDialogque não.

Você não deve substituir os dois métodos, porque provavelmente confundirá o Android sobre quando ou se o layout da sua caixa de diálogo foi inflado! WTF?

A escolha de substituir OnCreateDialogou OnCreateViewdepende de como você pretende usar a caixa de diálogo.

  • Se você iniciar o diálogo em uma janela (o comportamento normal), é esperado que você substitua OnCreateDialog.
  • Se você pretende incorporar o fragmento de diálogo a um layout de interface do usuário existente (FAR menos comum), espera-se que você substitua OnCreateView.

Esta é possivelmente a pior coisa do mundo.

onCreateDialog Insanidade

Portanto, você está substituindo o onCreateDialogseu DialogFragmentpara criar uma instância personalizada AlertDialogpara exibir em uma janela. Legal. Mas lembre-se, onCreateDialognão recebe ViewGrouppara anexar o costume .xml disposição para . Não tem problema, você simplesmente passa nullpara o inflatemétodo

Que a loucura comece.

Quando você substitui onCreateDialog, o Android ignora completamente vários atributos do nó raiz do layout .xml inflado. Isso inclui, mas provavelmente não está limitado a:

  • background_color
  • layout_gravity
  • layout_width
  • layout_height

Isto é quase cômico, como você é obrigado a definir a layout_widthe layout_heightde cada .xml Esquema ou Android Studio irá golpeá-lo com um belo distintivo pouco vermelho de vergonha.

Apenas a palavra DialogFragment me faz querer vomitar. Eu poderia escrever um romance cheio de truques e snafus para Android, mas este é um dos mais íntimos.

Para retornar à sanidade, primeiro declaramos um estilo para restaurar APENAS o background_colore 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>

O estilo acima herda do tema base para caixas de diálogo (no AppCompattema neste exemplo).

Em seguida, aplicamos o estilo programaticamente para colocar de volta os valores que o Android acabou de deixar de lado e restaurar a AlertDialogaparência padrão :

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

O código acima fará com que você AlertDialogpareça AlertDialognovamente. Talvez isso seja bom o suficiente.

Mas espere, tem mais!

Se você estiver olhando para definir um ESPECÍFICA layout_width ou layout_heightpara o seu AlertDialogquando ele é mostrado (muito provável), então acho que, você não é feito ainda!

A alegria continua quando você percebe que, se você tentar definir um estilo específico layout_widthou layout_heightdo seu novo estilo, o Android ignorará isso também !:

<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 definir a largura ou a altura de uma janela ESPECÍFICA, siga para um método completo e lide com 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);
}

Muitas pessoas seguem o mau exemplo do Android de usar WindowManager.LayoutParamso mais geral ViewGroup.LayoutParams, apenas para virar à direita e ViewGroup.LayoutParamsvoltar para WindowManager.LayoutParamsalgumas linhas depois. Java eficaz, que maldição desnecessária não oferece nada além de tornar o código ainda mais difícil de decifrar.

Nota lateral: existem algumas repetições de vinte e cinco vezes LayoutParamsno SDK do Android - um exemplo perfeito de design radicalmente ruim.

Em suma

Para DialogFragments que substituem onCreateDialog:

  • Para restaurar a AlertDialogaparência padrão , crie um estilo que defina background_color= transparente layout_gravity= centere aplique esse estilo onCreateDialog.
  • Para definir um específico layout_widthe / ou layout_height, faça-o programaticamente onResumecomLayoutParams
  • Para manter a sanidade, tente não pensar no SDK do Android.

13
Ler esta resposta me faz querer chorar.
Bassinator 7/07

3
Cara, você descreveu exatamente o que estou experimentando agora.
Mert Gülsoy

2
Android é uma merda. Eu sinto você, mano. precisando de um contexto para tudo, processo aplicativo mata, a falta de bibliotecas de apoio para algumas coisas, a lista continua
DennisVA

1
@rmirabelle - esta resposta realmente ajuda, você pode escrever um blog médio e pode ser útil para muitos. No meu caso, estou usando o layout de restrição e o DialogFragment, portanto, com o ignorar no Android 9, abaixo do Android 9, ele está funcionando bem. Eu adicionei - "android: windowMinWidthMajor, "Android: windowMinWidthMinor" em estilo e começou a trabalhar bem.
Rahul


14

Quando preciso tornar o DialogFragment um pouco mais amplo, estou definindo minWidth:

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

1
Melhor solução na minha opinião!
Fabian Knapp

e se você quiser torná-lo mais estreito?
Daniel

8

Eu não vejo uma razão convincente para substituir onResumeou onStartpara definir a largura e altura do Windowinterior DialogFragment's Dialog- estes métodos de ciclo de vida particulares podem obter chamado repetidamente e desnecessariamente executar esse redimensionamento código mais de uma vez devido a coisas como a janela de comutação multi, backgrounding em primeiro plano o aplicativo e assim por diante. As consequências dessa repetição são bastante triviais, mas por que se contentar com isso?

Definir a largura / altura em vez de um onActivityCreated()método substituído será uma melhoria, pois esse método realisticamente só é chamado uma vez por instância do seu DialogFragment. Por exemplo:

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

Acima, apenas defino a largura match_parentindependentemente da orientação do dispositivo. Se você deseja que a caixa de diálogo paisagem não seja tão ampla, verifique com getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAITantecedência.


6

A dimensão no layout mais externo não funciona na caixa de diálogo. Você pode adicionar um layout em que defina a dimensão abaixo da mais 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>


5

Corrigi-o definindo os parâmetros de layout do elemento raiz.

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

5

Aqui está uma maneira de definir a largura / altura do DialogFragment em xml. Apenas envolva sua viewHierarchy em um Framelayout (qualquer layout funcionará) com um plano de fundo transparente.

Um plano de fundo transparente parece ser um sinalizador especial, porque centraliza automaticamente o filho do frameLayout na janela quando você faz isso. Você ainda terá a tela cheia escurecendo atrás do seu fragmento, indicando que ele é o elemento ativo.

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

      .....

Vou tentar fazer isso porque, se funcionar de maneira consistente, é uma abordagem MUITO superior para codificar parte do layout em XML e parte dele no código. Graças
rmirabelle

Gosto da ideia dessa abordagem, mas quando testada, ela gera um layout diferente do que simplesmente alterar altura e largura programaticamente. Por exemplo, a largura geral é reduzida à força para a largura máxima oferecida por um AlertDialog (provavelmente por causa dos estilos do Android). Quando eu apenas defino we via código, o estilo AlertDialog é substituído. No entanto, isso pode atender a muitas necessidades e é uma ótima idéia. Viva o pior SDK da história.
precisa saber é o seguinte

Trabalhou muito para onCreateView, até que eu queria mudar a largura interna para match_parent ...
tudor

5

Aqui está a versão 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

Você pode usar porcentagem para largura.

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

Eu usei o Holo Theme para este exemplo.


3

Você pode codificar abaixo para definir a largura e a altura do layout do 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

Eu crio a caixa de diálogo usando AlertDialog.Builder, então usei a resposta de Rodrigo dentro de um 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 para futuros leitores :) Veja o comentário Snicolasna discussão de " DialogFragmentvs AlertDialog" em stackoverflow.com/a/7979823/3372061 .
Dev-iL

2

Trabalhando no Android 6.0, ocorreu o mesmo problema. AlertDialogteria como padrão o widthconjunto predefinido no tema, independentemente do widthconjunto real na raiz da visualização personalizada Layout. Consegui fazê-lo para ajustar corretamente widtho loading_message TextView. Sem investigar mais, parece que dimensionar os elementos reais e colocar a raiz em Layoutvolta deles faz com que funcione conforme o esperado. Abaixo está um layout XML de uma caixa de diálogo de carregamento, que define widthcorretamente a caixa de diálogo. Usando a biblioteca this para a animação.

<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

Fácil e sólido:

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

        super.onResume();
    }

2

No meu caso, DialogFragmentocupava o tamanho total da atividade como a Fragment. O DialogFragmentfoi baseado no layout XML, não AlertDialog. Meu erro foi adicionar o fragmento de diálogo FragmentManagercomo um fragmento usual:

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

Em vez disso, preciso showdo fragmento de diálogo:

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

Após algumas edições (eu tenho ViewPager2no layout), o fragmento de diálogo ficou muito estreito:

insira a descrição da imagem aqui

Eu usei a solução de N1hk :

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

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

Agora, ele definiu largura e altura, não o tamanho total da atividade.

Eu quero dizer sobre onCreateViewe onCreateDialog. Se você tiver um fragmento de diálogo com base no layout, poderá usar qualquer um desses 2 métodos.

1) Se você usar onCreateView, deverá onActivityCreateddefinir a largura.

2) Se você usar em onCreateDialogvez de onCreateView, poderá definir parâmetros lá. onActivityCreatednão será necessário.

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
}

Você salvou meu dia, definir a largura em onActivityCreated funcionou para mim.
Hagar Magdy 24/06

@ManishKumarSharma, boa sorte!
CoolMind 17/07

1

No meu caso, foi causado por align_parentBottom="true"uma visualização dentro de a RelativeLayout. Removidos todos os alignParentBottom e alterados todos os layouts para LinearLayouts verticais, e o problema desapareceu.


1

Defina o layout pai do layout de diálogo personalizado como RelativeLayout , obtenha largura e altura comuns automaticamente.

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

Isso funcionou para mim. Eu queria usar um ConstraintLayout para colocar os controles na minha caixa de diálogo, então usei um RelativeLayout para o layout raiz e, em seguida, coloquei um ConstraintLayout diretamente dentro dele. Isso me deu uma caixa de diálogo de tamanho normal. Quando eu coloco o ConstraintLayout como raiz, sem alterar mais nada, a largura da caixa de diálogo implode para não ser muito larga!
Leafcutter

1

Uma das soluções anteriores quase funcionou. Eu tentei algo um pouco diferente e acabou funcionando para mim.

(Certifique-se de olhar para a solução dele) Esta foi a solução dele. Clique aqui Funcionou, exceto: builder.getContext (). GetTheme (). ApplyStyle (R.style.Theme_Window_NoMinWidth, true);

Eu mudei para

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

A última linha é o que realmente é diferente.


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

Esta é a solução mais simples

A melhor solução que encontrei é substituir em onCreateDialog()vez de onCreateView(). setContentView () definirá as dimensões corretas da janela antes de inflar. Isso elimina a necessidade de armazenar / definir uma dimensão, cor de plano de fundo, estilo etc. nos arquivos de recursos e configurá-los 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

Adicione ao seu 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

Isso funcionará perfeitamente.

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

Isso é basicamente o que a resposta aceita de mais de 3 anos atrás diz.
Adil Hussain

-4

Para obter uma caixa de diálogo que cobre quase todos os seixos: Primeiro defina uma 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;
    }
}

Então você precisa chamar o ScreenParamater antes do método getDialog.getWindow (). SetLayout ()

@Override
public void onResume()
{
    super.onResume();
    ScreenParameters s = new ScreenParameters();
    getDialog().getWindow().setLayout(s.Width , s.Height);
}
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.