DialogFragment'ın genişliğini ve yüksekliğini nasıl ayarlayabilirim?


173

DialogFragment'ın düzenini bir xml mizanpaj dosyasında (diyelim layout_mydialogfragment.xml) layout_widthve layout_heightözellikle ve özniteliklerini ( 100dpher biri diyelim ki) belirtiyorum . Daha sonra bu düzeni DialogFragment'ın onCreateView(...)yönteminde aşağıdaki gibi şişiririm :

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

Ne yazık ki, iletişim kutum (DialogFragment) göründüğünde, xml mizanpaj dosyasında belirtilen layout_widthve layout_heightbelirtilenlere uymadığını (ve iletişim kutusum içeriğe bağlı olarak değiştiğini veya genişlediğini) görüyorum . Herkes benim xml mizanpaj dosyasında belirtilen layout_widthve layout_heightbelirtilen iletişim saygı alabilir olsun veya nasıl alabilirim ? Şu anda DialogFragment'ın onResume()yönteminde diyalogumun genişliğini ve yüksekliğini tekrar belirtmem gerekiyor ...

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

... Ve böylece, istenmeyen bir şekilde, iletişim kutusunun genişliğinde ve yüksekliğinde iki yerde gelecekte herhangi bir değişiklik yapmayı hatırlamak zorundadır.


2
Jpmcosta'un cevabını kabul etmeyi düşünün. Bu bir hack değil ve aslında sorunu çözüyor.
Bogdan Zurac

Yanıtlar:


168

Doğrudan kaynak değerlerinden dönüştürürseniz:

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

Ardından iletişim kutusunun düzeninde match_parent belirtin:

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

Sadece bir yer hakkında endişelenmeniz gerekiyor (içine yerleştirin DialogFragment#onResume). Mükemmel değil, ama en azından diyalogunuzun düzen dosyasının kökü olarak bir RelativeLayout'a sahip olmak için çalışıyor.


3
Bu cevap benim durumumda çalışmıyor (DialogFragment için). Gösteren pencerenin boyutunu değiştirmek için FragmentLayout params kullanmak zorunda kaldı.
Rusfearuth

3
Düzenimi sarmak zorunda kaldım RelativeLayoutve bana yardımcı oldu. Çözüm için çok teşekkürler - bana çok zaman kazandırdı.
Johnny Doe

62
Bu benim için harika çalışıyor (Android 4.0+), bunun olması gerektiğini fark ettikten sonra onResume()değil onCreateView(). (Benim kök düzenim bir ScrollView ile sarılmış RelativeLayout'tur.)
Jonik

14
Bazı durumlarda kullanışlıdır: tüm ekran genişliğini kullanın:int width = getResources().getDisplayMetrics().widthPixels
Jonik

6
Jonik için +1. Richard için -1. Her zaman destek parçalarını kullanıyorum ve hiç çalışamadım onCreateDialog(). İçinde olmak gerekiyor onResume().
MinceMan

146

Fragment.onResume()Altta yatan iletişim kutusundaki öznitelikleri geçersiz kılma ve kapma, sonra genişlik / yükseklik parametrelerini ayarladım. En dıştaki düzen yüksekliğini / genişliğini olarak ayarladım match_parent. Bu kodun xml düzeninde tanımladığım kenar boşluklarına da uyduğunu unutmayın.

@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
Teşekkürler ! Benim için çalışıyor! Dahası, bunu yapmanın zarif bir yoludur.
AntoineP

1
@jmaculate - Hızlı soru: Ne zaman yayın yapıyorsunuz (android.view.WindowManager.LayoutParams), ne yapıyorsunuz? LayoutParamsİşlevin ilk 3 satırında görünecek doğru içe aktarma seçildiğinde şaşkındım . Seçim bitti (android.view.WindowManager.LayoutParams). Bu doğru mu?
Dev-iL

@ Dev-iL getAttributes () bir WindowManger.LayoutParams döndürür, ancak benim durumumda dolaylı olarak ViewGroup.LayoutParams için döküm çünkü ihtiyacım olan tek şey (Etkili Java, Öğe 52) - Bunu yansıtmak için soruyu düzenleyeceğim
jmaculate

1
Tekrar yayınlamanız gerekiyorsa android.view.WindowManager.LayoutParams, ViewGroup.LayoutParamsyukarıdaki üç satırı kullanmak işe yaramaz ... Burada herhangi bir esneklik kazanmazsınız. Her neyse, bu iyi cevap için teşekkür ederim!
Kevin Robatel

2
Bu en iyi çözümdür. MATCH_PARENT veya WRAP_CONTENT ile birlikte belirli bir piksel değeri bile kullanabilirsiniz.
Koesh

98

Aşağıdaki XML ana düzeninde (benim durumumda LinearLayout) tanımlayan sabit bir boyut DialogFragment var:

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

4
Ben petek midWidth ve minHeight ihtiyacım bulundu - ama ICS değil.
daveywc

1
Bu ilk bakışta işe yarıyor gibi gözüküyor, ancak bundan kaçınılmalıdır. Görünüm, aygıtın genişliğine bağlı olarak ekrandan çıkmaya devam edecektir, böylece sağ alt köşede düğmeler varsa görünmezler.
CodyEngel

Görünüm ekran dışında devam etmiyor. Android sistemi, bu sınırlar belirtilen minWidth ve minHeight'tan daha küçük olsa bile, DialogFragment'ın görünüm sınırları içinde kalmasını sağlar (küçük bir kenar boşluğu ile).
Lensflare

51

Benim durumumda işe yarayan tek şey, burada işaret edilen çözümdü: http://adilatwork.blogspot.mx/2012/11/android-dialogfragment-dialog-sizing.html

Adil blog yazısından snippet:

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

Mükemmel çözüm ve blogda çok iyi açıklanmıştır.
varun bhardwaj

+1 getDialog().getWindow().setLayout(dialogWidth, dialogHeight); bir DialogFragment için mükemmel çalışır. Ama güvenlik kontrolünü anlamýyorum. neden kontrol etmeliyiz null?
tpk

3
@ 2943 - sadece Dialog(bir çocuğunun DialogFragment) istendiği zaman mevcut olacağının garantisi olmadığından . Aradığımızda Android'in null değerini döndürmesi mümkündür getDialog().
rmirabelle

@mirabelle iletişim kutusunun onStart geri araması ile iletişim kuruyorsanız, iletişim kutusu nasıl boş olabilir?
rommex

49

DialogFragmentGenişliğinizi ve yüksekliğini kontrol etmenin bir yolu , iletişim kutusunun değerleri varsa görünümünüzün genişliğine ve yüksekliğine saygı duymasını sağlamaktır WRAP_CONTENT.

kullanma ThemeOverlay.AppCompat.Dialog

Bunu başarmanın basit bir yolu ThemeOverlay.AppCompat.Dialog, Android Destek Kitaplığı'nda bulunan stili kullanmaktır .

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

DialogFragmentile AlertDialog(uyarı:) 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();
}

İletişim ThemeOverlay.AppCompat.Dialogkutularınızı oluştururken, uygulamanızın xml temasına ekleyerek varsayılan tema olarak da ayarlayabilirsiniz .
Dikkatli olun, çünkü birçok iletişim kutusunun iyi görünmesi için varsayılan minimum genişliğe ihtiyacı vardır.

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

DialogFragmentaşağıdakilerden Dialogyararlanarak 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;
}

DialogFragmentile AlertDialog, android:alertDialogThemeveya alertDialogTheme(uyarı:) kullanarak 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();
}

Bonus

Eski Android API'larında, Dialogadları nedeniyle bazı genişlik sorunları var gibi görünüyor (bir tane belirlemeseniz bile). Stili
kullanmak istemiyorsanız ThemeOverlay.AppCompat.Dialogve Dialogbir başlığa ihtiyacınız yoksa (veya özel bir stiliniz yoksa), devre dışı bırakmak isteyebilirsiniz:

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

Eski cevap, çoğu durumda çalışmaz

Diyalogun programlı olarak sabit bir boyut belirtmeden, düzenimin genişliğine ve yüksekliğine saygı duymaya çalışıyordum.

Bunu anladım android:windowMinWidthMinorve android:windowMinWidthMajorsoruna neden oluyordum. Benim temamda yer almasalar Activityda Dialog, yine de bir Activityşekilde temaya uygulanıyorlardı .

Üç olası çözüm buldum.

1.Çözüm: Özel bir iletişim kutusu teması oluşturun ve 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);
}

Çözüm 2: Bir kullanılmak üzere özel bir tema oluşturmak ContextThemeWrapperolarak görev alacağını Contextiletişim için. Özel bir iletişim kutusu teması oluşturmak istemiyorsanız bunu kullanın (örneğin, tarafından belirtilen temayı kullanmak istediğinizde 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());
}

(Bir ile Çözüm 3 AlertDialog): uygulamak android:windowMinWidthMinorve android:windowMinWidthMajoriçine ContextThemeWrapperyarattığı 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
Bunun neden kabul edilen cevap olmadığını gerçekten bilmiyorum. Bu tam anlamıyla çalışan ve bir kesmek değil tek cevap (Ben çoğunlukla 1. çözüm için konuşuyorum).
Bogdan Zurac

1
ne yazık ki bunu sadece nasıl çözeceğini anlayarak bir saat geçirdikten sonra buldum!
brainvision

Çözüm 3 hayatımı kurtarıyor. Çok teşekkür ederim
Simon

Sorununuzu eski Android API'larında yeniden oluşturabildim. Size yardımcı olabilecek bazı alternatifler eklendi.
jpmcosta

Çözüm 1 benim için çalıştı. ben sadece Theme.MaterialComponents.Light.Dialogebeveyn olarak kullanılan ve bu stil yapıcı kullanılır MaterialAlertDialogBuilder. 1 saatlik bir araştırmadan sonra cevabınızı tökezledi. Teşekkürler ve yaşasın.
Shahood ul Hassan

39

Anladım # 13: DialogFragmentDüzenler

Gerçekten biraz uyuşmuş gibi.

A oluştururken DialogFragment, geçersiz kılmayı onCreateView( ViewGroup.xml düzeninizi eklemek için a iletir) veya değiştirmez onCreateDialog.

Her iki yöntemi de geçersiz kılmamalısınız, çünkü Android'i iletişim kutusunun düzeninin ne zaman şişip bitmediğine veya karıştırılmayacağına büyük olasılıkla karıştıracaksınız! O NE LAN?

Geçersiz kılmayı OnCreateDialogveya OnCreateViewiletişim kutusunu nasıl kullanmayı planladığınıza bağlı olarak seçim yapma .

  • İletişim kutusunu bir pencerede başlatacaksanız (normal davranış), geçersiz kılmanız beklenir OnCreateDialog.
  • İletişim parçasını mevcut bir kullanıcı arayüzü düzenine (FAR daha az yaygın) gömmek istiyorsanız, geçersiz kılmanız beklenir OnCreateView.

Bu muhtemelen dünyadaki en kötü şey.

onCreateDialog cinnet

Yani, geçersiz kılma ediyoruz onCreateDialogGözlerinde farklı DialogFragmentözelleştirilmiş bir örneğini oluşturmak için AlertDialogbir pencerede ekrana. Güzel. Ama unutmayın, onCreateDialoghiçbir alır ViewGroup.xml düzen sizin özel takmak için için . Sorun, sadece geçmesi nulliçin inflateyöntemle.

Çılgınlık başlasın.

Geçersiz kıldığınızda onCreateDialog, Android, şişirdiğiniz .xml Mizanpajı'nın kök düğümünün birkaç niteliğini TAMAMEN İZLEMEKTEDİR . Bu aşağıdakileri içerir, ancak muhtemelen bunlarla sınırlı değildir:

  • background_color
  • layout_gravity
  • layout_width
  • layout_height

Ayarlamak için gereken gibi bu neredeyse komik layout_widthve layout_heightutanç güzel küçük kırmızı rozeti ile tokat olacak her .xml Düzeni veya Android Studio.

Sadece kelime DialogFragment kusmamı istiyor. Android gotchas ve snafus ile dolu bir roman yazabilirdim, ama bu en insülüslerden biri.

Aklımıza dönmek için, ilk olarak, SADECE geri yüklemek için bir stil ilan ediyoruz background_colorve layout_gravitybekliyoruz:

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

Yukarıdaki stil, Diyaloglar için temel temayı devralır ( AppCompatbu örnekteki temada).

Ardından, Android'i bir kenara attığımız değerleri geri getirmek ve standart görünümü ve hissi geri yüklemek için stili programlı olarak uygularızAlertDialog :

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

Yukarıdaki kod AlertDialogbir AlertDialogkez daha görünmenizi sağlayacaktır . Belki bu yeterince iyi.

Ama bekleyin, dahası var!

Bir SPECIFIC ayarlamak layout_widthveya gösterildiğinde (büyük olasılıkla) arıyorsanız layout_height, AlertDialogne olduğunu tahmin edin, henüz yapmadınız!

Komiklik, belirli layout_widthveya layout_heightsüslü yeni tarzınızda belirlemeye çalışırsanız , Android'in de bunu tamamen görmezden geleceğini fark ettiğinizde devam ediyor !:

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

SPECIFIC pencere genişliği veya yüksekliği ayarlamak için, bir bütün 'nuther yöntemine gidip aşağıdakilerle başa çıkabilirsiniz 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);
}

Birçok kişi, Android'in WindowManager.LayoutParamsdaha genel olana kadar kötü örneklerini izliyor ViewGroup.LayoutParams, sadece sağa ViewGroup.LayoutParamsdönüp WindowManager.LayoutParamsbirkaç satıra geri dönüyor . Etkili Java lanet olsun, bu gereksiz döküm kodu deşifre daha da zor hale getirmek dışında HİÇBİR ŞEY sunuyor.

Yan not: LayoutParamsAndroid SDK'nın bazı yirmili tekrarları var - radikal olarak zayıf tasarımın mükemmel bir örneği.

Özetle

İçin DialogFragmentşu kilit s onCreateDialog:

  • Standart AlertDialoggörünümü ve hissi geri yüklemek için , background_color= transparentve layout_gravity= ayarlayan bir stil oluşturun centerve bu stili uygulayın onCreateDialog.
  • Bir özgü ayarlamak için layout_widthve / veya layout_heightiçinde programlı bunu onResumebirlikteLayoutParams
  • Akıl sağlığını korumak için Android SDK'sını düşünmemeye çalışın.

13
Bu cevabı okumak beni ağlatmak istiyor.
Bassinator

3
Dostum, şu an yaşadığım şeyi tam olarak açıkladın.
Mert Gülsoy

2
Android boktan bir şey. Seni anlıyorum kardeşim. her şey için bir içeriğe ihtiyaç duyuyor, uygulama süreci öldürüyor, bazı şeyler için destek kütüphaneleri yok, liste uzayıp gidiyor
DennisVA

1
@rmirabelle - bu cevap aslında yardımcı olur, aslında orta bir blog yazabilir ve birçokları için yararlı olabilir. Benim durumumda kısıtlama düzeni ve DialogFragment kullanıyorum, bu yüzden Android 9'da göz ardı edildi, Android 9'un altında iyi çalışıyor. Ben ekledim - "android: windowMinWidthMajor," android: windowMinWidthMinor "tarzında ve iyi çalışmaya başladı.
Rahul


14

DialogFragment biraz daha geniş yapmak gerektiğinde minWidth ayarlıyorum:

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

1
Bence en iyi çözüm!
Fabian Knapp

ya da daha dar yapmak istiyorsan?
Daniel

8

Ben geçersiz kılmak için zorlayıcı bir neden görmüyorum onResumeveya onStartgenişliğini ve yüksekliğini ayarlamak için Windowiçinde DialogFragment'nin Dialog- bu özel yaşam döngüsü yöntemleri defalarca ve gereksiz yere denilen alabilirsiniz çalıştırması nedeniyle çoklu pencere anahtarlama gibi şeylere kereden fazla kod yeniden boyutlandırma, arkatasar daha sonra uygulamayı ön planda tutma vb. Bu tekrarlamanın sonuçları oldukça önemsizdir, ama neden buna razı olun?

Bunun yerine geçersiz kılınmış bir onActivityCreated()yöntem içinde genişliği / yüksekliği ayarlamak bir iyileştirme olacaktır, çünkü bu yöntem gerçekçi bir şekilde sizin örneğinizde yalnızca bir kez çağrılır DialogFragment. Örneğin:

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

Yukarıda, genişliği match_parentcihazın yönüne bakılmaksızın ayarladım . Yatay iletişim pencerenizin bu kadar geniş olmamasını istiyorsanız, getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAITönceden olup olmadığını kontrol edebilirsiniz .


6

En dıştaki mizanpajdaki boyut iletişim kutusunda çalışmaz. Ayarlanan boyutu en dışın altına yerleştirdiğiniz bir düzen ekleyebilirsiniz.

<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

Kök eleman düzen parametrelerini ayarlayarak düzelttim.

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

5

DialogFragment genişliğini / yüksekliğini xml olarak ayarlamanın bir yolu. ViewHierarchy'yi şeffaf bir arka plana sahip bir Framelayout'a (herhangi bir düzen işe yarayacak) sarmanız yeterlidir.

Saydam bir arka plan özel bir bayrak gibi görünür, çünkü bunu yaptığınızda frameLayout'un alt öğesini otomatik olarak pencerede ortalar. Tam ekranın parçanızın arkasında kararmasını sağlamaya devam edersiniz, bu da parçanızın aktif öğe olduğunu gösterir.

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

      .....

Ben tutarlı bir şekilde çalışırsa, XML düzeninin bir kısmını ve kodun bir kısmını kodlamak için VASTLY üstün bir yaklaşım bu bir deneyeceğim. Teşekkürler
rmirabelle

Bu yaklaşım fikrini seviyorum, ancak test edildiğinde, programlı olarak yükseklik ve genişliği değiştirmekten farklı bir düzen sunuyor. Örneğin, toplam genişlik, bir AlertDialog tarafından sağlanan maksimum genişliğe zorla azaltılır (muhtemelen Android stilleri nedeniyle). W ve h koduyla ayarladığımda, AlertDialog stili geçersiz kılındı. Ancak bu birçok ihtiyaca uyabilir ve iyi bir fikirdir. Yaşasın tarihin en kötü SDK'sı.
rmirabelle

İç genişliği match_parent olarak değiştirmek isteyinceye kadar onCreateView için harika çalıştım ...
tudor

5

İşte kotlin versiyonu

    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

Genişlik için yüzde kullanabilirsiniz.

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

Bu örnek için Holo Tema kullandım.


3

Java'nın düzen genişliğini ve yüksekliğini ayarlamak için kodun altında yapabilirsiniz.

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

AlertDialog.Builder kullanarak iletişim kutusu oluşturmak, böylece bir OnShowListener içinde Rodrigo yanıtını kullandım.

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

        });

(Özellikle gelecekteki okuyucular için :) stackoverflow.com/a/7979823/3372061 adresindeki " vs " Snicolastartışmasında açıklamaya bakın . DialogFragmentAlertDialog
Dev-iL

2

Android 6.0'da çalışmak da aynı sorunla karşılaştı. özel görünümün kökündeki gerçek kümeden bağımsız olarak temada AlertDialogönceden tanımlanmış widthküme varsayılanı olur . Ben düzgün ayarlama ayarlamak için elde edebildi arasında . Daha fazla araştırma yapmadan, gerçek unsurların boyutlandırılması ve etraflarında kök sargısının olması, beklendiği gibi çalışmasını sağlıyor gibi görünüyor. Aşağıda, iletişim kutusunu doğru şekilde ayarlayan bir yükleme iletişim kutusunun XML düzeni bulunur . Animasyon için bu kütüphaneyi kullanma .widthLayoutwidthloading_message TextViewLayoutwidth

<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

Kolay ve sağlam:

@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

Benim durumumda DialogFragmenttam aktivite büyüklüğü gibi işgal etti Fragment. DialogFragmentXML-düzeni değil dayanıyordu AlertDialog. Benim hatam iletişim parçası FragmentManagerolağan bir parçası olarak eklemek oldu :

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

Bunun yerine showiletişim parçasına ihtiyacım var :

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

Bazı düzenlemelerden sonra ( ViewPager2mizanpajda var) iletişim parçası çok dardı:

resim açıklamasını buraya girin

N1hk çözümünü kullandım :

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

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

Şimdi tam aktivite boyutunu değil, genişlik ve yüksekliği tanımladı.

Ben hakkında söylemek istiyorum onCreateViewve onCreateDialog. Düzene dayalı bir iletişim kutusu parçanız varsa, bu 2 yöntemden herhangi birini kullanabilirsiniz.

1) kullanıyorsanız onCreateView, onActivityCreatedgenişliği ayarlamak için kullanmalısınız .

2) onCreateDialogBunun yerine kullanırsanız onCreateView, parametreleri buradan ayarlayabilirsiniz. onActivityCreatedgerekmeyecek.

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
}

OnActivityCreated'da genişliği ayarlayarak günümü kaydettiniz benim için çalıştı.
Hagar Magdy

@ManishKumarSharma, iyi şanslar!
CoolMind

1

Benim durumumda align_parentBottom="true", a içindeki bir görüşe neden oldu RelativeLayout. Tüm alignParentBottom'ları kaldırıldı ve tüm düzenleri dikey LinearLayouts olarak değiştirdi ve sorun gitti.


1

Özel diyalog düzeninin üst düzenini RelativeLayout olarak ayarlayın , ortak genişlik ve yüksekliği otomatik olarak alın.

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

Bu benim için çalıştı. Kök düzeni için bir RelativeLayout kullandım ve sonra doğrudan içine bir ConstraintLayout koymak böylece benim iletişim denetimleri düzenlemek için bir ConstraintLayout kullanmak istedim. Bu bana normal boyutlu bir diyalog verdi. Ben başka bir şey değiştirmeden kök olarak ConstraintLayout koymak sonra iletişim genişliği çok geniş değil imploded!
leafcutter

1

Önceki çözümlerden biri neredeyse işe yaradı. Biraz farklı bir şey denedim ve benim için çalışmaya başladı.

( Çözümüne baktığınızdan emin olun) Bu onun çözümüydü .. Burayı Tıklayın Şunlar dışında çalıştı: builder.getContext (). GetTheme (). Camerastyle (R.style.Theme_Window_NoMinWidth, true);

Olarak değiştirdim

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

Son satır gerçekten farklı.


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

Bu en basit çözüm

Bulduğum en iyi çözüm onCreateDialog()yerine geçersiz kılmak onCreateView(). setContentView (), şişirmeden önce doğru pencere boyutlarını ayarlar. Kaynak dosyalarında bir boyut, arka plan rengi, stil vb. Saklama / ayarlama ve bunları manuel olarak ayarlama ihtiyacını ortadan kaldırır.

@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

Ekle 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

Bu mükemmel bir şekilde çalışacaktır.

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

Bu, 3+ yıl önce kabul edilen cevabın hemen hemen söylediği şey.
Adil Hussain

-4

Neredeyse tüm dağınıklığı kapsayan bir İletişim Kutusu almak için: Önce bir ScreenParameter sınıfı tanımlayın

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

Ardından getDialog.getWindow (). SetLayout () yönteminizden önce ScreenParamater öğesini çağırmanız gerekir

@Override
public void onResume()
{
    super.onResume();
    ScreenParameters s = new ScreenParameters();
    getDialog().getWindow().setLayout(s.Width , s.Height);
}
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.