Як керувати шириною та висотою діалогового вікна попередження за замовчуванням в Android?


76
AlertDialog.Builder builder = new AlertDialog.Builder(this);
        builder.setTitle("Title");
        builder.setItems(items, new DialogInterface.OnClickListener() {
            public void onClick(DialogInterface dialog, int item) {
                Toast.makeText(getApplicationContext(), items[item], Toast.LENGTH_SHORT).show();
            }
        });
        AlertDialog alert = builder.create();

Я використовую наведений вище код для відображення діалогового вікна попередження. За замовчуванням він заповнює екран по ширині та wrap_content по висоті.
Як я можу контролювати ширину та висоту діалогового вікна попередження за замовчуванням?
Я намагався:

alert.getWindow().setLayout(100,100); // It didn't work.

Як отримати параметри макета у вікні попередження та вручну встановити ширину та висоту?

Відповіді:


204

Лише незначна зміна Sat Code, встановіть макет після show()методу AlertDialog.

AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setView(layout);
builder.setTitle("Title");
alertDialog = builder.create();
alertDialog.show();
alertDialog.getWindow().setLayout(600, 400); //Controlling width and height.

Або ви можете зробити це по-моєму.

alertDialog.show();
WindowManager.LayoutParams lp = new WindowManager.LayoutParams();

lp.copyFrom(alertDialog.getWindow().getAttributes());
lp.width = 150;
lp.height = 500;
lp.x=-170;
lp.y=100;
alertDialog.getWindow().setAttributes(lp);

1
@ingo: так, можна, створіть xml, який належить до діалогового вікна, і в цьому xml створіть свій текст, як dialog.setContentView (R.layout.dialog); а в xml ви можете робити що завгодно з текстом.
ПіюшМішра

2
@PiyushMishra Як встановити heightта widthяку підтримку підтримувати всі Пристрої.
Пратік Бутані

2
+1 для after show () ... Був у цьому протягом 2 годин і не міг змусити його працювати до цього.
Крусео

1
@PratikButani це лише зразок, для динамічної висоти потрібно написати певний алгоритм, наприклад, спочатку обчислити висоту та ширину екрана, а потім відповідно до нього можна розділити висоту та ширину діалогового вікна та його розміщення також.
PiyushMishra

1
важливо змінити розмір ПІСЛЯ виклику методу show. Мені це зайняло занадто багато часу, щоб усвідомити це.
Альберто М

28

Добре, я можу контролювати ширину та висоту за допомогою класу Builder. я використав

AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setView(layout);
builder.setTitle("Title");
AlertDialog alertDialog = builder.create();
alertDialog.getWindow().setLayout(600, 400); //Controlling width and height.
alertDialog.show();

Відмінний улов. Після create () набагато краще, ніж після show (), особливо, якщо використовується DialogFragments!
Робін Девіс,

Ви не використовуєте клас builder для зміни ширини / висоти, просто об’єкт alertDialog
Патрік Фавр

3
у мене це не працювало між створенням та шоу, а лише після шоу.
Альберто М

Повинна встановити ширину вікна в програмі прослуховування шоу.
Джеффрі Блаттман,

18

Перш ніж намагатися налаштувати розмір після розмітки, спочатку перевірте, який стиль використовується у вашому діалоговому вікні. Переконайтеся, що в дереві стилів немає нічого

<item name="windowMinWidthMajor">...</item>
<item name="windowMinWidthMinor">...</item>

Якщо це відбувається, це так само просто, як надання власного стилю [конструктору конструктора, який бере темуResId] ( http://developer.android.com/reference/android/app/AlertDialog.Builder.html#AlertDialog.Builder (android.content.Context , int)) доступний API 11+

<style name="WrapEverythingDialog" parent=[whatever you were previously using]>
    <item name="windowMinWidthMajor">0dp</item>
    <item name="windowMinWidthMinor">0dp</item>
</style>

Дякую, набагато простіше, ніж робити це програмно.
v1k

1
Як я можу знайти тему, яку використовує діалогове вікно? Я можу лише здогадуватися.
Леос Літерак

14

Для тих, хто знайде цю тему, як я, ось найкраще рішення для IMO (зверніть увагу на 70%, яке встановлює мінімальну ширину діалогу у відсотках до ширини екрану):

<style name="my_dialog" parent="Theme.AppCompat.Dialog.Alert">
    <item name="windowMinWidthMajor">70%</item>
    <item name="windowMinWidthMinor">70%</item>
</style>

А потім застосуйте цей стиль до діалогового вікна:

AlertDialog.Builder builder = new AlertDialog.Builder(context, R.style.my_dialog);

Використовувати відсотки зі стилем набагато простіше, ніж робити програмно
Атаберк,

11

Це також працює, додаючи .getWindow().setLayout(width, height)післяshow()

alertDialogBuilder
            .setMessage("Click yes to exit!")
            .setCancelable(false)
            .setPositiveButton("Yes",new DialogInterface.OnClickListener() {
                public void onClick(DialogInterface dialog,int id) {
                    // if this button is clicked, close
                    // current activity
                    MainActivity.this.finish();
                }
              })
            .setNegativeButton("No",new DialogInterface.OnClickListener() {
                public void onClick(DialogInterface dialog,int id) {
                    // if this button is clicked, just close
                    // the dialog box and do nothing
                    dialog.cancel();
                }
            }).show().getWindow().setLayout(600,500);

не міг змусити його працювати будь-яким способом, окрім цього, тому +1 для вас. Дякую!
Брент,

9

Якщо ви хочете додати динамічну ширину та висоту на основі кадру вашого пристрою, ви можете зробити ці обчислення та призначити висоту та ширину.

 AlertDialog.Builder builderSingle = new 
 AlertDialog.Builder(getActivity());
 builderSingle.setTitle("Title");

 final AlertDialog alertDialog = builderSingle.create();
 alertDialog.show();

 Rect displayRectangle = new Rect();
 Window window = getActivity().getWindow();

 window.getDecorView().getWindowVisibleDisplayFrame(displayRectangle);

 alertDialog.getWindow().setLayout((int)(displayRectangle.width() * 
 0.8f), (int)(displayRectangle.height() * 0.8f));

PS: Спочатку покажіть діалогове вікно, а потім спробуйте змінити атрибути макета вікна


Що робити, якщо я не хочу змінювати висоту?
Пратік Бутані

"PS: спочатку показати діалогове вікно, а потім спробувати змінити атрибути макета вікна" працює як шарм!
Аджай-Дадхал,

4

Я не знаю, чи можете ви змінити висоту / ширину за замовчуванням AlertDialog, але якщо ви хотіли це зробити, я думаю, ви можете це зробити, створивши власне власне діалогове вікно. Вам просто потрібно вказати android:theme="@android:style/Theme.Dialog" android manifest.xml для своєї діяльності і ви можете написати весь макет відповідно до ваших вимог. Ви можете встановити висоту та ширину власного діалогового вікна з XML ресурсу Android.


Це може спрацювати, але я не хотів додавати іншу діяльність. Я розмістив рішення, яке використовував. Дякую.
сб

Так, вищезазначений метод теж працює для показу елементів у спливаючому стилі або скажімо в діалоговому стилі попередження. Просто спробував це в одному з проектів.
сб

Щойно порівняли 2 способи: 1. З AlertDialog.builder та ще 2. активність із діалогом теми, другий є кращим рішенням, лише недоліком є ​​те, що якщо потрібно відправити деякі результати назад у фоновий режим, потрібно використовувати startActivityForResult, оскільки елементи перегляди) у фоновій діяльності недоступні.
сб

4

Оцініть відповідь Сід, оскільки це динамічно, але я хочу щось додати.

Що робити, якщо ви хочете змінити лише ширину, висота буде такою, якою вона є.

Я зробив наступне:

    // All process of AlertDialog
    AlertDialog alert = builder.create();
    alert.show();

    // Creating Dynamic
    Rect displayRectangle = new Rect();

    Window window = getActivity().getWindow();
    window.getDecorView().getWindowVisibleDisplayFrame(displayRectangle);
    alert.getWindow().setLayout((int) (displayRectangle.width() *
            0.8f), alert.getWindow().getAttributes().height);

Тут я звик alert.getWindow().getAttributes().heightдотримуватися висоти такою, якою вона є, AlertDialogі Widthбуде змінюватися відповідно до роздільної здатності екрана.

Сподіваюся, це допоможе. Дякую.


3
longButton.setOnClickListener {
  show(
    "1\n2\n3\n4\n5\n6\n7\n8\n9\n0\n" +
      "1\n2\n3\n4\n5\n6\n7\n8\n9\n0\n" +
      "1\n2\n3\n4\n5\n6\n7\n8\n9\n0\n" +
      "1\n2\n3\n4\n5\n6\n7\n8\n9\n0\n" +
      "1\n2\n3\n4\n5\n6\n7\n8\n9\n0\n" +
      "1\n2\n3\n4\n5\n6\n7\n8\n9\n0\n" +
      "1234567890-12345678901234567890123456789012345678901234567890"
  )
}

shortButton.setOnClickListener {
  show(
    "1234567890\n" +
      "1234567890-12345678901234567890123456789012345678901234567890"
  )
}

private fun show(msg: String) {
  val builder = AlertDialog.Builder(this).apply {
    setPositiveButton(android.R.string.ok, null)
    setNegativeButton(android.R.string.cancel, null)
  }

  val dialog = builder.create().apply {
    setMessage(msg)
  }
  dialog.show()

  dialog.window?.decorView?.addOnLayoutChangeListener { v, _, _, _, _, _, _, _, _ ->
    val displayRectangle = Rect()
    val window = dialog.window
    v.getWindowVisibleDisplayFrame(displayRectangle)
    val maxHeight = displayRectangle.height() * 0.6f // 60%

    if (v.height > maxHeight) {
      window?.setLayout(window.attributes.width, maxHeight.toInt())
    }
  }
}

коротке повідомлення

довге повідомлення


2

Я думаю, що відповідь tir38 - це найчистіше рішення. Майте на увазі, що якщо ви використовуєте теми android.app.AlerDialog та holo, ваш стиль повинен виглядати так

<style name="WrapEverythingDialog" parent=[holo theme ex. android:Theme.Holo.Dialog]>
    <item name="windowMinWidthMajor">0dp</item>
    <item name="windowMinWidthMinor">0dp</item>
</style>

І якщо ви використовуєте support.v7.app.AlertDialog або androidx.appcompat.app.AlertDialog з темою AppCompat, ваш стиль повинен виглядати так

<style name="WrapEverythingDialog" parent=[Appcompat theme ex. Theme.AppCompat.Light.Dialog.Alert]>
    <item name="android:windowMinWidthMajor">0dp</item>
    <item name="android:windowMinWidthMinor">0dp</item>
</style>

Ви щойно скопіювали відповідь tir38
Aiko West
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.