Pokaż AlertDialog w dowolnej pozycji ekranu

106

Kiedy pokazujemy AlertDialog na Androidzie, pokazuje się on na środku ekranu. Czy jest jakiś sposób na zmianę pozycji?

gypsicoder
źródło

Odpowiedzi:

255

Po przeszukaniu różnych postów znalazłem rozwiązanie.

Kod znajduje się poniżej:

private CharSequence[] items = {"Set as Ringtone", "Set as Alarm"};
    AlertDialog.Builder builder = new AlertDialog.Builder(this);
    builder.setItems(items, new DialogInterface.OnClickListener() {
        public void onClick(DialogInterface dialog, int item) {

            if(item == 0) {

            } else if(item == 1) {

            } else if(item == 2) {

            }
        }
    });

     AlertDialog dialog = builder.create();
     dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
     WindowManager.LayoutParams wmlp = dialog.getWindow().getAttributes();

 wmlp.gravity = Gravity.TOP | Gravity.LEFT;
 wmlp.x = 100;   //x position
 wmlp.y = 100;   //y position

 dialog.show();

Tutaj wartość pozycji x to piksele od lewej do prawej. Dla pozycji y wartość jest od dołu do góry.

gypsicoder
źródło
1
Możesz także utworzyć niestandardowe okno dialogowe ostrzeżenia. Niedawno to zrobiłem, a następnie musiałem uzyskać szerokość i wysokość wyświetlaczy, a następnie ustawić X i Y na podstawie procentu tych wartości, dzięki czemu układ był ładnie skalowany. developer.android.com/guide/topics/ui/dialogs.html#CustomDialog
Roloc
15
Działa, ale musiałem dodać to: WMLP.gravity = Gravity.TOP | Gravity.LEFT; w przeciwnym razie wartości x i y były używane jako przesunięcia od środka ekranu.
BoD
1
Tylko po to, by podzielić się doświadczeniem: powyższy kod działa tylko tak długo, jak długo okno dialogowe może pozostać na ekranie. Na przykład, jeśli nowa współrzędna y jest zbyt duża, okno dialogowe jest przenoszone do najniższej pozycji na ekranie, która nadal pokazuje całe okno dialogowe. Problem polega na tym, że wartości x i y parametrów układu nie pokazują już współrzędnych lewego górnego rogu okna dialogowego i nie można ich użyć do obliczenia względnego ruchu okna, na przykład gdy reagowanie na MotionEvent.
Nantoka,
1
działa jak uroku ..ale nie ma potrzeby, aby ustawić wmlp.x = 100; //x position wmlp.y = 100;po prostu zestaw grawitacja wmlp.gravity = Gravity.TOP | Gravity.LEFT;jest na tyle
Ajay Mistry
14

Jeśli na przykład chcesz przesunąć okno dialogowe postępu nieco niżej i nie ustawiać dokładnej pozycji piksela, to wystarczy:

progressDialog.getWindow().getAttributes().verticalMargin = 0.2F;
pgsandstrom
źródło
Chcę przeznaczyć około 10 dp marginesu na okno dialogowe ostrzeżenia, którego grawitacja znajduje się w środku. Czy mogę użyć powyższego kodu? Jeśli nie, to czy można to zrobić w inny sposób?
Aman Verma
5

Aby ustawienie miało efekt informacyjny, dodałem następujący kod
dialog.getWindow().setAttributes(wmlp);

po zmianie wartości wmlp w odpowiedzi gypsicodera lub ustawienie wmlp nie jest uwzględniane przez mój test.

juejiang
źródło
0

Te odpowiedzi spowodują przesunięcie pozycji AlertDialog, jednak pozycja wyświetlanego okna dialogowego będzie również zawierać wypełnienie wokół okna.

Jeśli chcesz pozbyć się tego wypełnienia (na przykład, aby umieścić okno dialogowe równo z dolną częścią ekranu), będziesz również musiał nadpisać domyślny styl AlertDialog w swoim styles.xml, aby ustawić windowBackground na null, tak jak w poniższym przykładzie :

<resources>
    <!--  Example app theme - mine uses the below -->
    <style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
        <item name="android:alertDialogTheme">@style/MyDialogTheme</item>
    </style>

    <style name="MyDialogTheme" parent="Theme.AppCompat.Light.Dialog.Alert">
    <!-- Full width -->
        <item name="android:layout_width">fill_parent</item>

    <!-- Null window background kills surrounding padding -->
        <item name="android:windowBackground">@null</item>
        <item name="android:windowNoTitle">true</item>

     </style>
</resources> 

Oprócz ustawienia Window.LayoutParameters zgodnie z opisem w zaakceptowanej odpowiedzi.

Specjalne pozdrowienie dla @Davida Caunta, którego odpowiedź pod adresem: usuń obramowanie, dopełnienie z okna dialogowego uzupełniło ten obraz.

HappyKatz
źródło