Jak wyświetlić okno dialogowe Tak / Nie na Androidzie?

358

Tak, wiem, że istnieje AlertDialog.Builder, ale jestem zszokowany tym, jak trudno (cóż, przynajmniej nie przyjazny dla programisty) wyświetlić okno dialogowe w Androidzie.

Kiedyś byłem programistą .NET i zastanawiam się, czy istnieje coś podobnego do Androida?

if (MessageBox.Show("Sure?", "", MessageBoxButtons.YesNo) == DialogResult.Yes){
    // Do something...
}
Solo
źródło
3
Jak mogę ponownie wygenerować kod AlertDialog i obsługiwać zdarzenia (tak, żadnych akcji) na wszystkich ekranach? W .Net używamy klasy Action do obsługi zdarzeń, czy jest jakiś sposób, aby to zaimplementować? Wiem, że za pomocą interfejsów możemy to zrobić, ale w inny sposób?
Ravikumar11
2
Tak ... my, programiści .NET, naprawdę ciężko jest nam pracować z Androidem ... Zastanawiam się, czy Xamarin jest świetnym narzędziem?
Daniel Möller

Odpowiedzi:

745

AlertDialog.Builder naprawdę nie jest trudny w użyciu. Na początku jest to trochę onieśmielające, ale gdy trochę go użyjesz, jest zarówno proste, jak i potężne. Wiem, że powiedziałeś, że wiesz, jak go używać, ale i tak oto prosty przykład:

DialogInterface.OnClickListener dialogClickListener = new DialogInterface.OnClickListener() {
    @Override
    public void onClick(DialogInterface dialog, int which) {
        switch (which){
        case DialogInterface.BUTTON_POSITIVE:
            //Yes button clicked
            break;

        case DialogInterface.BUTTON_NEGATIVE:
            //No button clicked
            break;
        }
    }
};

AlertDialog.Builder builder = new AlertDialog.Builder(context);
builder.setMessage("Are you sure?").setPositiveButton("Yes", dialogClickListener)
    .setNegativeButton("No", dialogClickListener).show();

Możesz także użyć tego ponownie, DialogInterface.OnClickListenerjeśli masz inne pola typu tak / nie , które powinny zrobić to samo.

Jeśli tworzysz okno dialogowe z poziomu a View.OnClickListener, możesz użyć, view.getContext()aby uzyskać kontekst. Alternatywnie możesz użyć yourFragmentName.getActivity().

Steve Haley
źródło
3
nowy AlertDialog.Builder (this); Błąd czasu kompilacji: „Konstruktor AlertDialog.Builder (nowy View.OnClickListener () {}) jest niezdefiniowany”
Eric Leschinski,
3
Proste i przydatne okno dialogowe zniknie po kliknięciu przez użytkownika przycisku „TAK” lub „NIE”. Nie musisz nic robić.
RRTW
9
Ja sam używałem go wiele razy. Ale odkryłem, że w rzeczywistości łatwiej i szybciej jest sprawdzić to na SO. Podany tutaj przykład kodu jest tak prosty ... Naprawdę chciałbym, aby dokumentacja Androida wyglądała tak.
Radu
4
@EricLeschinski prawdopodobnie „to” nie jest kontekstem, spróbuj tego: AlertDialog.Builder builder = new AlertDialog.Builder(getView().getContext());
cldrr
1
@davidglorioso Kolejność tak / nie lub nie / tak zależy od wersji Androida i nie można jej kontrolować. Nie pamiętam, kiedy to się zmieniło, ale myślę, że to było w wersji 4.x lub 5. Mówiąc to, i tak nie powinieneś tego zmieniać. Wszystkie aplikacje, które używają standardowych okien dialogowych alertów, będą używać tej samej kolejności przycisków nie / tak i byłoby to mylące dla użytkowników, gdyby Twoje były inne. Jeśli naprawdę chcesz, aby było inaczej, musisz ręcznie ustawić pozytywne / negatywne przyciski w zależności od wersji Androida.
Steve Haley
163

Spróbuj tego:

AlertDialog.Builder builder = new AlertDialog.Builder(this);

builder.setTitle("Confirm");
builder.setMessage("Are you sure?");

builder.setPositiveButton("YES", new DialogInterface.OnClickListener() {

    public void onClick(DialogInterface dialog, int which) {
        // Do nothing but close the dialog

        dialog.dismiss();
    }
});

builder.setNegativeButton("NO", new DialogInterface.OnClickListener() {

    @Override
    public void onClick(DialogInterface dialog, int which) {

        // Do nothing
        dialog.dismiss();
    }
});

AlertDialog alert = builder.create();
alert.show();
nikki
źródło
25
Osobiście bardziej podoba mi się ten fragment kodu niż zaakceptowana odpowiedź
Jan
1
@nikki dlaczego oba mają lekceważenie ()?
likejudo
The constructor AlertDialog.Builder(MainActivity.DrawerItemClickListener) is undefined
hash
@ likejiujitsu, ponieważ chcesz wyczyścić okno dialogowe z pamięci w każdym przypadku po zakończeniu pracy.
Avi Levin
32

Odpowiedź Steve'a H jest natychmiastowa, ale oto nieco więcej informacji: okna dialogowe działają tak, jak działają, ponieważ okna dialogowe w Androidzie są asynchroniczne (wykonywanie nie zatrzymuje się, gdy okno dialogowe jest wyświetlane). Z tego powodu musisz użyć wywołania zwrotnego, aby obsłużyć wybór użytkownika.

Sprawdź to pytanie, aby uzyskać dłuższą dyskusję między różnicami w systemach Android i .NET (w odniesieniu do okien dialogowych): Dialogi / AlertDialogs: Jak „zablokować wykonywanie”, gdy okno dialogowe jest uruchomione (w stylu .NET)

Erich Douglass
źródło
8
Dzięki temu, że okna dialogowe Androida są asynchroniczne, teraz wszystko jest jasne (i rozsądne). Wydaje się, że muszę „wymyślić .Net” podczas tworzenia aplikacji dla Androida :)
Solo
Do waszej informacji: to, co nazywacie „dialogem asynchronicznym”, w terminologii GUI nazywa się „dialogem bezmodelowym”, podczas gdy „okno synchroniczne” nazywa się „dialogem modalnym”. Android nie ma modalnych okien dialogowych (z wyjątkiem bardzo wyjątkowych przypadków).
Alex
Android nie zezwala na modalne okna dialogowe z bardzo ważnego powodu: nie może zakłócać działania innych aplikacji na urządzeniu.
Renascienza
14

To działa dla mnie:

AlertDialog.Builder builder = new AlertDialog.Builder(getApplicationContext());

    builder.setTitle("Confirm");
    builder.setMessage("Are you sure?");

    builder.setPositiveButton("YES", new DialogInterface.OnClickListener() {

        public void onClick(DialogInterface dialog, int which) {

            // Do nothing, but close the dialog
            dialog.dismiss();
        }
    });

    builder.setNegativeButton("NO", new DialogInterface.OnClickListener() {

        @Override
        public void onClick(DialogInterface dialog, int which) {

            // Do nothing
            dialog.dismiss();
        }
    });

    AlertDialog alert = builder.create();
    alert.show();
haszysz
źródło
7

Pytanie osoby, czy chce zadzwonić, czy nie Dialog ..

import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.ImageView;
import android.widget.Toast;

public class Firstclass extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {    
        super.onCreate(savedInstanceState);    
        setContentView(R.layout.first);

        ImageView imageViewCall = (ImageView) findViewById(R.id.ring_mig);

        imageViewCall.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v){
                try{
                    showDialog("0728570527");
                } catch (Exception e){
                    e.printStackTrace();
                }                   
            }    
        });    
    }

    public void showDialog(final String phone) throws Exception {
        AlertDialog.Builder builder = new AlertDialog.Builder(Firstclass.this);

        builder.setMessage("Ring: " + phone);       

        builder.setPositiveButton("Ring", new DialogInterface.OnClickListener(){
            @Override
            public void onClick(DialogInterface dialog, int which){

                Intent callIntent = new Intent(Intent.ACTION_DIAL);// (Intent.ACTION_CALL);                 
                callIntent.setData(Uri.parse("tel:" + phone));
                startActivity(callIntent);

                dialog.dismiss();
            }
        });

        builder.setNegativeButton("Abort", new DialogInterface.OnClickListener(){   
            @Override
            public void onClick(DialogInterface dialog, int which){
                dialog.dismiss();
            }
        });         
        builder.show();
    }    
}
Zar E Ahmer
źródło
5

Odpowiedź Stevesa jest poprawna, choć nieaktualna z fragmentami. Oto przykład z FragmentDialog.

Klasa:

public class SomeDialog extends DialogFragment {

    @Override
    public Dialog onCreateDialog(Bundle savedInstanceState) {
        return new AlertDialog.Builder(getActivity())
            .setTitle("Title")
            .setMessage("Sure you wanna do this!")
            .setNegativeButton(android.R.string.no, new OnClickListener() {
                @Override
                public void onClick(DialogInterface dialog, int which) {
                    // do nothing (will close dialog)
                }
            })
            .setPositiveButton(android.R.string.yes,  new OnClickListener() {
                @Override
                public void onClick(DialogInterface dialog, int which) {
                    // do something
                }
            })
            .create();
    }
}

Aby uruchomić okno dialogowe:

            FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
            // Create and show the dialog.
            SomeDialog newFragment = new SomeDialog ();
            newFragment.show(ft, "dialog");

Możesz także pozwolić klasie zaimplementować onClickListeneri używać tego zamiast wbudowanych detektorów.

Warpzit
źródło
@likejiujitsu powyżej jest wystarczające.
Warpzit,
Utwórz klasę FragmentDialog, aby zrobić pole „nie / tak” to trochę przesadzenie ... :) Domyślny AlertDialog jest jeszcze wystarczająco sprawiedliwy.
Renascienza
@Renascienza tak, ale uważam, że jest przestarzały.
Warpzit,
Nie całkiem. FragmentDialog został dodany jako przydatna rzecz, która pozwala na ponowne użycie fragmentu w oknie dialogowym. Fragmenty dotyczą ponownego użycia interfejsu użytkownika. Ponieważ nie potrzebujesz używać fragmentów tylko dlatego, że jest to nowa rzecz (fragmenty nie przychodzą, aby zastąpić działania), nie musisz używać FragmentDialog w przypadkach, w których nie ma żadnej korzyści. Na przykład proste powiadomienia Tak / Nie.
Renascienza
2
Polecam: jeśli potrzebujesz ponownie użyć nie tylko układu, ale także kodu tła i cyklu życia, skorzystaj z okna dialogowego Fragment. Za pomocą tego fragmentu masz powiązaną kontrolę cyklu życia aktywności i możesz reagować na zdarzenia takie jak tworzenie (gdy interfejs użytkownika jest tworzony ponownie, gdy użytkownik obraca urządzenie), pauza, wznawianie itp. W skrócie, okno dialogowe z rozbudowanym interfejsem użytkownika. Jeśli nie potrzebujesz tego, a twoje okno dialogowe jest dość proste, zwykłe okna dialogowe działają dobrze.
Renascienza
5

Dzięki nikki twoja odpowiedź pomogła mi ulepszyć istniejącą, po prostu dodając pożądane działanie w następujący sposób

AlertDialog.Builder builder = new AlertDialog.Builder(this);

builder.setTitle("Do this action");
builder.setMessage("do you want confirm this action?");

builder.setPositiveButton("YES", new DialogInterface.OnClickListener() {

    public void onClick(DialogInterface dialog, int which) {
        // Do do my action here

        dialog.dismiss();
    }

});

builder.setNegativeButton("NO", new DialogInterface.OnClickListener() {

    @Override
    public void onClick(DialogInterface dialog, int which) {
        // I do not need any action here you might
        dialog.dismiss();
    }
});

AlertDialog alert = builder.create();
alert.show();
CrandellWS
źródło
Mam wrażenie, że OP nie chciał używać AlertDialog.Builder. OP chce wiedzieć, czy istnieje metoda użyteczności skrótu,
walrii 11.11
1
Napisałem ten sam kod, ale najpierw pojawia się NIE, a następnie TAK w zasadzie jest to okno dialogowe NIE / TAK, ale potrzebuję okna dialogowego TAK / NIE Jak to zrobić
Sagar Devanga
Jeśli chodzi o TAK / NIE vs NIE / TAK, zobacz tę odpowiedź: stackoverflow.com/a/13644589/1815624 możesz nią manipulować zgodnie z opisem w tej odpowiedzi: stackoverflow.com/a/13644536/1815624
CrandellWS
4

W Kotlinie:

AlertDialog.Builder(this)
    .setTitle(R.string.question_title)
    .setMessage(R.string.question_message)
    .setPositiveButton(android.R.string.yes) { _, _ -> yesClicked() }
    .setNegativeButton(android.R.string.no) { _, _ -> noClicked() }
    .show()
Cristan
źródło
3

Pokaż anonimowo okno dialogowe jako ciąg poleceń i bez definiowania innego obiektu:

 new AlertDialog.Builder(this).setTitle("Confirm Delete?")
                        .setMessage("Are you sure?")
                        .setPositiveButton("YES",
                                new DialogInterface.OnClickListener() {
                                    public void onClick(DialogInterface dialog, int which) {

                                       // Perform Action & Dismiss dialog                                 
                                        dialog.dismiss();
                                    }
                                })
                        .setNegativeButton("NO", new DialogInterface.OnClickListener() {
                            @Override
                            public void onClick(DialogInterface dialog, int which) {
                                // Do nothing
                                dialog.dismiss();
                            }
                        })
                        .create()
                        .show();
Hitesh Sahu
źródło
2

Wszystkie odpowiedzi tutaj sprowadzają się do długiego i nieprzyjaznego dla czytelnika kodu: tego, czego osoba próbująca próbowała uniknąć. Dla mnie najłatwiejszym rozwiązaniem było zatrudnienie tutaj lambdów:

new AlertDialog.Builder(this)
        .setTitle("Are you sure?")
        .setMessage("If you go back you will loose any changes.")
        .setPositiveButton("Yes", (dialog, which) -> {
            doSomething();
            dialog.dismiss();
        })
        .setNegativeButton("No", (dialog, which) -> dialog.dismiss())
        .show();

Lambdas na Androida wymaga wtyczki retrolambda ( https://github.com/evant/gradle-retrolambda ), ale i tak jest bardzo pomocny w pisaniu czystszego kodu.

javaxian
źródło
1

Dzięki. Używać API Poziom 2 (Mobile 1.1) i zamiast BUTTON_POSITIVEa BUTTON_NEGATIVEi użyć BUTTON1i BUTTON2.

chrześcijanin
źródło
1

1. Utwórz alert Ustaw wiadomość, tytuł i znak pozytywny, przycisk negatywny:

final AlertDialog alertDialog = new AlertDialog.Builder(this)
                        .setCancelable(false)
                        .setTitle("Confirmation")
                        .setMessage("Do you want to remove this Picture?")
                        .setPositiveButton("Yes",null)
                        .setNegativeButton("No",null)
                        .create();

2. Teraz znajdź oba przyciski na DialogInterface Kliknij, a następnie setOnClickListener ():

alertDialog.setOnShowListener(new DialogInterface.OnShowListener() {
            @Override
            public void onShow(DialogInterface dialogInterface) {
                Button yesButton = (alertDialog).getButton(android.app.AlertDialog.BUTTON_POSITIVE);
                Button noButton = (alertDialog).getButton(android.app.AlertDialog.BUTTON_NEGATIVE);
                yesButton.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View view) {
                        //Now Background Class To Update Operator State
                        alertDialog.dismiss();
                        Toast.makeText(GroundEditActivity.this, "Click on Yes", Toast.LENGTH_SHORT).show();
                        //Do Something here 
                    }
                });

                noButton.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View view) {
                        alertDialog.dismiss();
                        Toast.makeText(GroundEditActivity.this, "Click on No", Toast.LENGTH_SHORT).show();
                        //Do Some Thing Here 
                    }
                });
            }
        });

3. Aby wyświetlić Alertdialog:

alertDialog.show();

Uwaga: Nie zapomnij końcowego słowa kluczowego za pomocą AlertDialog.

Wajid Khan
źródło
0
AlertDialog.Builder altBx = new AlertDialog.Builder(this);
    altBx.setTitle("My dialog box");
    altBx.setMessage("Welcome, Please Enter your name");
    altBx.setIcon(R.drawable.logo);

    altBx.setPositiveButton("Ok", new DialogInterface.OnClickListener()
    {
      public void onClick(DialogInterface dialog, int which)
      {
          if(edt.getText().toString().length()!=0)
          {
              // Show any message
          }
          else 
          {

          }
      }
    });
    altBx.setNeutralButton("Cancel", new DialogInterface.OnClickListener()
    {
      public void onClick(DialogInterface dialog, int which)
      {
          //show any message
      }

    });
  altBx.show();  
Singhak
źródło
0

możesz wdrożyć ogólne rozwiązanie dla decyzji i użyć w innym przypadku nie tylko dla tak / nie i dostosować alert za pomocą animacji lub układu:

Coś takiego; najpierw utwórz swoją klasę do przesyłania danych:

public class AlertDecision {

    private String question = "";
    private String strNegative = "";
    private String strPositive = "";

    public AlertDecision question(@NonNull String question) {
        this.question = question;
        return this;
    }

    public AlertDecision ansPositive(@NonNull String strPositive) {
        this.strPositive = strPositive;
        return this;
    }

    public AlertDecision ansNegative(@NonNull String strNegative) {
        this.strNegative = strNegative;
        return this;
    }

    public String getQuestion() {
        return question;
    }

    public String getAnswerNegative() {
        return strNegative;
    }

    public String getAnswerPositive() {
        return strPositive;
    }
}

po interfejsie do zwrócenia wyniku

public interface OnAlertDecisionClickListener {

    /**
     * Interface definition for a callback to be invoked when a view is clicked.
     *
     * @param dialog the dialog that was clicked
     * @param object The object in the position of the view
     */
    void onPositiveDecisionClick(DialogInterface dialog, Object object);
    void onNegativeDecisionClick(DialogInterface dialog, Object object);
}

Teraz możesz łatwo utworzyć narzędzia do dostępu (w tej klasie możesz zaimplementować inną animację lub niestandardowy układ alertu):

public class AlertViewUtils {

    public static void showAlertDecision(Context context,
                                         @NonNull AlertDecision decision,
                                         final OnAlertDecisionClickListener listener,
                                         final Object object) {

        AlertDialog.Builder builder = new AlertDialog.Builder(context);
        builder.setMessage(decision.getQuestion());
        builder.setPositiveButton(decision.getAnswerPositive(),
                new DialogInterface.OnClickListener() {
                    public void onClick(DialogInterface dialog, int which) {
                        listener.onPositiveDecisionClick(dialog, object);
                    }
                });

        builder.setNegativeButton(decision.getAnswerNegative(),
                new DialogInterface.OnClickListener() {
                    public void onClick(DialogInterface dialog, int which) {
                        listener.onNegativeDecisionClick(dialog, object);
                    }
                });

        android.support.v7.app.AlertDialog dialog = builder.create();
        dialog.show();
    }
}

i ostatnie wezwanie w działaniu lub fragmencie; możesz użyć tego w swoim przypadku lub do innego zadania:

public class MainActivity extends AppCompatActivity {

@Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity);
        initResources();
    }

    public void initResources() {
        Button doSomething = (Button) findViewById(R.id.btn);
        doSomething.setOnClickListener(getDecisionListener());
    }

    private View.OnClickListener getDecisionListener() {
        return new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                AlertDecision decision = new AlertDecision()
                        .question("question ...")
                        .ansNegative("negative action...")
                        .ansPositive("positive action... ");
                AlertViewUtils.showAlertDecision(MainActivity.this,
                        decision, getOnDecisionListener(), v);
            }
        };
    }

    private OnAlertDecisionClickListener getOnDecisionListener() {
        return new OnAlertDecisionClickListener() {
            @Override
            public void onPositiveDecisionClick(DialogInterface dialog, Object object) {

                //do something like create, show views, etc...
            }

            @Override
            public void onNegativeDecisionClick(DialogInterface dialog, Object object) {
                //do something like delete, close session, etc ...
            }
        };
    }
} 
Alex Zaraos
źródło
0

Możesz to zrobić tak łatwo w Kotlin:

 alert("Testing alerts") {
    title = "Alert"
    yesButton { toast("Yess!!!") }
    noButton { }
}.show()
Serg Burlaka
źródło
0

Dla Kotlin w Androidzie ::

    override fun onBackPressed() {
        confirmToCancel()
    }

    private fun confirmToCancel() {
        AlertDialog.Builder(this)
            .setTitle("Title")
            .setMessage("Do you want to cancel?")
            .setCancelable(false)
            .setPositiveButton("Yes") {
                dialog: DialogInterface, _: Int ->
                dialog.dismiss()
                // for sending data to previous activity use
                // setResult(response code, data)
                finish()
            }
            .setNegativeButton("No") {
                dialog: DialogInterface, _: Int ->
                dialog.dismiss()
            }
            .show()
    } 
Partha Paul
źródło
0

Wdrożenie Kotlin.

Możesz utworzyć taką prostą funkcję:

fun dialogYesOrNo(
        activity: Activity,
        title: String,
        message: String,
        listener: DialogInterface.OnClickListener
    ) {
        val builder = AlertDialog.Builder(activity)
        builder.setPositiveButton("Yes", DialogInterface.OnClickListener { dialog, id ->
            dialog.dismiss()
            listener.onClick(dialog, id)
        })
        builder.setNegativeButton("No", null)
        val alert = builder.create()
        alert.setTitle(title)
        alert.setMessage(message)
        alert.show()
    }

i nazwij to tak:

dialogYesOrNo(
  this,
  "Question",
  "Would you like to eat?",
  DialogInterface.OnClickListener { dialog, id ->
    // do whatever you need to do when user presses "Yes"
  }
})
chrześcijanin
źródło