Wie steuere ich die Breite und Höhe des Standard-Warndialogs in 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();

Ich verwende den obigen Code, um einen Warnungsdialog anzuzeigen. Standardmäßig wird der Bildschirm in der Breite und der Inhalt in der Höhe umwickelt.
Wie kann ich die Breite und Höhe des Standardalarmdialogs steuern?
Ich habe es versucht:

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

Wie kann ich die Layout-Parameter im Warnfenster abrufen und die Breite und Höhe manuell einstellen?

saß
quelle

Antworten:

203

Nur eine geringfügige Änderung im Sat-Code, legen Sie das Layout nach der show()Methode von fest 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.

Oder du kannst es auf meine Weise tun.

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);
PiyushMishra
quelle
1
@ingo: Ja, Sie können, erstellen Sie eine XML gehören zum Dialogfeld und entwerfen Sie in dieser XML Ihren Text wie dialog.setContentView (R.layout.dialog); und in xml kann man mit dem text alles machen.
PiyushMishra
2
@PiyushMishra Wie man einstellt heightund widthwelche Unterstützung für alle Geräte.
Pratik Butani
2
+1 für After Show () ... Ich war 2 Stunden dabei und konnte es bis dahin nicht zum Laufen bringen.
Cruceo
1
@PratikButani es ist nur ein Beispiel, für die dynamische Höhe müssen Sie bestimmte Algo schreiben, wie zuerst die Höhe und Breite des Bildschirms berechnen und dann entsprechend die Höhe und Breite des Dialogs und seine Platzierung auch unterteilen.
PiyushMishra
1
Es ist wichtig, die Größe zu ändern, nachdem die Methode show aufgerufen wurde. Ich habe zu lange gebraucht, um das zu realisieren.
Alberto M
28

Ok, ich kann die Breite und Höhe mit der Builder-Klasse steuern. ich benutzte

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();
saß
quelle
Hervorragender Fang. Nach create () ist WAY besser als nach show (), insbesondere wenn Sie DialogFragments verwenden!
Robin Davies
Sie verwenden nicht die Builder-Klasse, um die Breite / Höhe zu ändern, sondern nur das alertDialog-Objekt
Patrick Favre
3
Es hat bei mir zwischen dem Erstellen und der Show nicht funktioniert, sondern erst nach der Show.
Alberto M
Sollte die Fensterbreite in einem On-Show-Listener einstellen.
Jeffrey Blattman
17

Bevor Sie versuchen, die Größe nach dem Layout anzupassen, überprüfen Sie zunächst, welchen Stil Ihr Dialogfeld verwendet. Stellen Sie sicher, dass nichts im Stilbaum festgelegt ist

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

In diesem Fall ist es genauso einfach, dem [Builder-Konstruktor, der eine themeResId aufnimmt] ( http://developer.android.com/reference/android/app/AlertDialog.Builder.html#AlertDialog.Builder) Ihren eigenen Stil zuzuweisen (android.content.Context , int)) verfügbare API 11+

<style name="WrapEverythingDialog" parent=[whatever you were previously using]>
    <item name="windowMinWidthMajor">0dp</item>
    <item name="windowMinWidthMinor">0dp</item>
</style>
tir38
quelle
Vielen Dank, viel einfacher als programmgesteuert.
v1k
1
Wie finde ich das von einem Dialog verwendete Thema? Ich kann nur raten.
Leos Literak
13

Für diejenigen, die diesen Thread wie mich finden, gibt es hier eine bessere IMO-Lösung (beachten Sie die 70%, mit denen die minimale Breite des Dialogfelds in Prozent der Bildschirmbreite festgelegt wird):

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

Wenden Sie diesen Stil dann auf den Dialog an:

AlertDialog.Builder builder = new AlertDialog.Builder(context, R.style.my_dialog);
vovan888
quelle
Die Verwendung des Prozentsatzes mit Stil ist viel einfacher als die programmgesteuerte
Erstellung
11

Dies funktioniert auch durch Hinzufügen von .getWindow().setLayout(width, height)aftershow()

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);
Señorhak
quelle
konnte es nicht zum Laufen bringen, außer auf diese Weise, also +1 für dich. Vielen Dank!
Brent
9

Wenn Sie eine dynamische Breite und Höhe basierend auf Ihrem Geräterahmen hinzufügen möchten, können Sie diese Berechnungen durchführen und die Höhe und Breite zuweisen.

 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: Zeigen Sie zuerst den Dialog an und versuchen Sie dann, die Layoutattribute des Fensters zu ändern

Sid
quelle
Was ist, wenn ich die Höhe nicht ändern möchte?
Pratik Butani
"PS: Zeige zuerst den Dialog und versuche dann, die Layoutattribute des Fensters zu ändern" funktioniert wie ein Zauber!
Ajay Dhadhal
4

Ich weiß nicht, ob Sie die Standardhöhe / -breite von AlertDialog ändern können, aber wenn Sie dies möchten, können Sie dies tun, indem Sie Ihren eigenen benutzerdefinierten Dialog erstellen. Sie müssen nur android:theme="@android:style/Theme.Dialog" die android manifest.xml für Ihre Aktivität angeben und können das gesamte Layout gemäß Ihren Anforderungen schreiben. Sie können die Höhe und Breite Ihres benutzerdefinierten Dialogfelds im Android Resource XML festlegen.

MegaMind
quelle
Es könnte funktionieren, aber ich wollte keine weitere Aktivität hinzufügen. Ich habe die Lösung gepostet, die ich verwendet habe. Vielen Dank.
saß
Ja, die obige Methode funktioniert auch, um Elemente im Popup-Stil oder im Alarmdialogstil anzuzeigen. Habe es gerade in einem der Projekte ausprobiert.
saß
Nur zwei Möglichkeiten verglichen: 1. Mit AlertDialog.builder und einer anderen 2. Aktivität mit dem Thema Dialog ist die zweite eine bessere Lösung. Der einzige Nachteil ist, dass man startActivityForResult verwenden muss, da Elemente ( Ansichten) in Hintergrundaktivität sind nicht verfügbar.
saß
4

Schätzen Sie die Antwort von Sid, weil es dynamisch ist, aber ich möchte etwas hinzufügen.

Was ist, wenn Sie nur die Breite ändern möchten? Die Höhe bleibt unverändert.

Ich habe Folgendes getan:

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

Hier habe ich alert.getWindow().getAttributes().heightdie Höhe beibehalten AlertDialogund sie Widthwird gemäß der Bildschirmauflösung geändert.

Hoffe es wird helfen. Vielen Dank.

Pratik Butani
quelle
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())
    }
  }
}

Kurznachricht

lange Nachricht

Changhoon
quelle
1

Ich denke, die Antwort von tir38 ist die sauberste Lösung. Denken Sie daran, dass Ihr Stil so aussehen sollte, wenn Sie android.app.AlerDialog- und Holo-Themen verwenden

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

Und wenn Sie support.v7.app.AlertDialog oder androidx.appcompat.app.AlertDialog mit AppCompat-Design verwenden, sollte Ihr Stil so aussehen

<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>
user2610355
quelle
Sie haben gerade die Antwort von tir38 kopiert
Aiko West