Как отобразить диалоговое окно Да / Нет на Android?

358

Да, я знаю, что есть AlertDialog.Builder, но я потрясен, узнав, насколько сложно (по крайней мере, не для программистов) отображать диалог в Android.

Раньше я был разработчиком .NET, и мне интересно, есть ли Android-эквивалент следующего?

if (MessageBox.Show("Sure?", "", MessageBoxButtons.YesNo) == DialogResult.Yes){
    // Do something...
}
Соло
источник
3
Как возобновить код AlertDialog и обрабатывать события (да, без действий) на всех экранах? В .Net мы используем класс Action для обработки событий, есть ли способ реализовать это? Я знаю, используя интерфейсы, мы можем сделать это, но любым другим способом?
Ravikumar11
2
Да .... нам .NET-разработчикам действительно тяжело с android .... Интересно, Xamarin - отличный инструмент?
Даниэль Мёллер

Ответы:

745

AlertDialog.Builder действительно не так сложно использовать. Поначалу это немного пугает, но когда вы немного его используете, это одновременно и просто, и мощно. Я знаю, вы сказали, что знаете, как его использовать, но в любом случае вот простой пример:

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

Вы также можете использовать это повторно, DialogInterface.OnClickListenerесли у вас есть другие блоки да / нет, которые должны делать то же самое.

Если вы создаете диалог изнутри View.OnClickListener, вы можете использовать его view.getContext()для получения контекста. В качестве альтернативы вы можете использовать yourFragmentName.getActivity().

Стив Хейли
источник
3
новый AlertDialog.Builder (это); Ошибка времени компиляции: «Конструктор AlertDialog.Builder (новый View.OnClickListener () {}) не определен»
Эрик Лещинский
3
Простой и полезный, между прочим, диалог закрывается после нажатия пользователем кнопки «ДА» или «НЕТ». Вам ничего не нужно делать.
RRTW
9
Я сам, я использовал это много раз. Но я обнаружил, что на самом деле проще и быстрее найти его на SO. Приведенный здесь пример кода очень прост ... Мне бы очень хотелось, чтобы документация по Android выглядела так.
Раду
4
@EricLeschinski, вероятно, «это» не является контекстом, попробуйте это: AlertDialog.Builder builder = new AlertDialog.Builder(getView().getContext());
cldrr
1
@davidglorioso Порядок да / нет или нет / да зависит от версии Android, и вы не можете управлять им. Я не помню, когда это изменилось, но я думаю, что это было в 4.x или 5. Сказав это, вы не должны менять это в любом случае. Все приложения, использующие стандартные диалоговые окна оповещений, будут использовать один и тот же порядок кнопок «нет / да», и для пользователей было бы непонятно, если бы у вас было другое. Если вы действительно хотите, чтобы он был другим, вам придется вручную устанавливать свои положительные / отрицательные кнопки в зависимости от версии Android.
Стив Хейли
163

Попробуй это:

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
источник
25
Лично мне этот фрагмент кода нравится больше, чем принятый ответ
Джон
1
@nikki почему у обоих есть dismiss ()?
как
The constructor AlertDialog.Builder(MainActivity.DrawerItemClickListener) is undefined
хэш
@likejiujitsu, потому что вы хотите очистить диалоговое окно из памяти в любом случае после выполнения вашей работы.
Ави Левин
32

Ответ Стива Н точен, но вот немного больше информации: причина, по которой диалоги работают так, как они работают, состоит в том, что диалоги в Android асинхронны (выполнение не останавливается, когда диалоговое окно отображается). Из-за этого вы должны использовать обратный вызов для обработки выбора пользователя.

Проверьте этот вопрос для более подробного обсуждения различий в Android и .NET (в том, что касается диалогов): Dialogs / AlertDialogs: как «заблокировать выполнение», когда диалог открыт (стиль .NET)

Эрих Дуглас
источник
8
Спасибо, тот факт, что диалоги Android являются асинхронными, теперь все понятно (и разумно). Кажется, мне нужно «думать о .Net» при разработке приложений для Android :)
Solo
К вашему сведению: то, что вы называете «асинхронным диалогом», называется «немодальным диалогом» в терминологии GUI, тогда как «синхронный диалог» называется «модальным диалогом». Android не поддерживает модальные диалоги (кроме исключительных случаев).
Алекс
Android не разрешает системные модальные диалоги по очень веской причине: не допускается вмешательство в другие приложения на устройстве.
Renascienza
14

Это работает для меня:

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();
гашиш
источник
7

Спрашивая человека, хочет ли он позвонить или нет Диалог ..

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
источник
5

Ответ Стивса правильный, хотя и устаревший с фрагментами. Вот пример с FragmentDialog.

Класс:

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

Чтобы начать диалог:

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

Вы также можете позволить классу реализовать onClickListenerи использовать это вместо встроенных слушателей.

Warpzit
источник
@likejiujitsu выше достаточно.
Warpzit
Создать класс FragmentDialog просто для того, чтобы заполнить поле «нет / да», немного излишне ... :) По умолчанию AlertDialog достаточно честен.
Renascienza
@Renascienza да, но я считаю, что это устарело.
Warpzit
На самом деле, нет. FragmentDialog был добавлен как полезная вещь, чтобы позволить вам повторно использовать фрагмент в диалоге. Фрагменты это все о повторном использовании пользовательского интерфейса. Поскольку вам не нужно использовать фрагменты только потому, что это новая вещь (фрагменты не заменяют действия), вам не нужно использовать FragmentDialog в тех случаях, когда нет никакой выгоды. Например, просто оповещения Да / Нет.
Renascienza
2
Моя рекомендация: если вам нужно повторно использовать не только макет, но и фон и код жизненного цикла, используйте диалог Fragment. С фрагментом у вас есть связанный элемент управления жизненным циклом активности, и вы можете реагировать на такие события, как создание (так как пользовательский интерфейс воссоздается, когда пользователь поворачивает свое устройство), пауза, возобновление и т. Д. В двух словах, диалог с некоторым сложным пользовательским интерфейсом. Если вам это не нужно и ваш диалог довольно прост, обычные диалоги работают нормально.
Renascienza
5

Спасибо, Никки, твой ответ помог мне улучшить существующее, просто добавив желаемое действие следующим образом.

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
источник
У меня сложилось впечатление, что ОП не хочет использовать AlertDialog.Builder. ОП хочет знать, существует ли метод ярлыков,
walrii
1
Я написал тот же код, но сначала появляется НЕТ, а затем ДА, в основном это диалоговое окно НЕТ / ДА, но мне нужно диалоговое окно ДА / НЕТ Как мне это сделать
Сагар Деванга
Что касается ДА / НЕТ против НЕТ / ДА, см. Ответ: stackoverflow.com/a/13644589/1815624, вы можете манипулировать им, как описано в этом ответе: stackoverflow.com/a/13644536/1815624
CrandellWS
4

В Котлине:

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
источник
3

Показать диалог анонимно в виде цепочки команд и без определения другого объекта:

 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();
Хите саху
источник
2

Все ответы здесь сводятся к длинному и не удобному для читателя коду: то, чего пытался избежать человек, спрашивающий. Для меня самый простой подход - использовать здесь лямбды:

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 в Android требуется плагин retrolambda ( https://github.com/evant/gradle-retrolambda ), но в любом случае он чрезвычайно полезен при написании более чистого кода.

javaxian
источник
1

Спасибо. Я использую API Level 2 (Android 1.1), а вместо BUTTON_POSITIVEи BUTTON_NEGATIVEя должен использовать BUTTON1и BUTTON2.

Кристиан
источник
1

1. Создать AlertDialog установить сообщение, заголовок и положительный, отрицательный кнопку:

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. Теперь найдите обе кнопки на DialogInterface. Нажмите затем 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.Показать Alertdialog:

alertDialog.show();

Примечание: не забывайте Final Keyword с AlertDialog.

Ваджид хан
источник
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
источник
0

Вы можете реализовать общее решение для принятия решений и использовать его в другом случае, а не только для ответа «да / нет» и настраивать оповещение с анимацией или макетом:

Что-то вроде этого; Сначала создайте свой класс для передачи данных:

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

после интерфейса для возврата результата

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

Теперь вы можете легко создавать утилиты для доступа (в этом классе вы можете реализовать другую анимацию или собственный макет для оповещения):

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

и последний вызов в деятельности или фрагмент; Вы можете использовать это в вашем случае или для другой задачи:

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 ...
            }
        };
    }
} 
Алекс Зараос
источник
0

Вы можете сделать это так просто в Kotlin:

 alert("Testing alerts") {
    title = "Alert"
    yesButton { toast("Yess!!!") }
    noButton { }
}.show()
Серг Бурлака
источник
0

Для Котлина в Android ::

    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()
    } 
Партха Пол
источник
0

Реализация котлина.

Вы можете создать простую функцию, подобную этой:

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

и назовите это так:

dialogYesOrNo(
  this,
  "Question",
  "Would you like to eat?",
  DialogInterface.OnClickListener { dialog, id ->
    // do whatever you need to do when user presses "Yes"
  }
})
Кристиан
источник