Як відобразити діалогове вікно "Так / Ні" на 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якщо у вас є інші поля " так / ні", які повинні робити те саме.

Якщо ви створюєте діалог ізсередини a View.OnClickListener, ви можете view.getContext()отримати контекст. Можна також використовувати yourFragmentName.getActivity().


3
новий AlertDialog.Builder (це); Помилка часу компіляції: "Конструктор AlertDialog.Builder (новий View.OnClickListener () {}) не визначений"
Ерік Лещинський

3
Просте і корисне, btw, діалогове вікно закриється після натискання користувачем кнопки "ТАК" або "НІ". Нічого не потрібно робити.
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();

25
Особисто мені подобається цей фрагмент коду більше, ніж прийнята відповідь
Іван

1
@nikki, чому обидва мають відмінити ()?
likejudo

The constructor AlertDialog.Builder(MainActivity.DrawerItemClickListener) is undefined
хеш

@likejiujitsu, тому що ви хочете очистити діалогове вікно з пам'яті в будь-якому випадку після виконання вашої роботи.
Аві Левін

32

Відповідь Стіва Н - це місце, але ось трохи більше інформації: причина діалогів працює так, як вони, - це те, що діалоги в Android асинхронні (виконання не припиняється, коли з'явиться діалогове вікно). Через це вам потрібно використовувати зворотний дзвінок, щоб обробити вибір користувача.

Вивчіть це питання для більш тривалого обговорення відмінностей Android та .NET (як це стосується діалогів): Діалоги / AlertDialogs: Як "блокувати виконання", коли діалогове вікно працює (.NET-стиль)


8
Дякуємо, той факт, що діалоги Android асинхронні, робить усе зрозумілим (і розумним) вже зараз. Здається, мені потрібно «додумати .Net» під час розробки програм для Android :)
Соло

FYI: те, що ви називаєте "асинхронним діалогом", в термінології GUI називається "діалоговим режимом", тоді як "синхронний діалог" називається "модальним діалогом". Android не має модальних діалогів (за винятком дуже виняткових випадків).
Олексій

Android не дозволяє системні модальні діалоги з дуже поважної причини: заборонено втручатися в інші програми на пристрої.
Ренасьєнза

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

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та використовувати це замість вбудованих слухачів.


@likejiujitsu вище є достатнім.
Warpzit

Створення класу FragmentDialog просто для того, щоб зробити поле "не / так" - це трохи переоформлення ... :) Але AlertDialog за замовчуванням є досить справедливим.
Ренасьєнза

@Renascienza так, але я вважаю, що це застаріло.
Warpzit

Не зовсім. FragmentDialog був доданий як корисна річ, що дозволяє повторно використовувати фрагмент у діалоговому вікні. Фрагменти - це все про повторне використання інтерфейсу. Оскільки вам не потрібно використовувати фрагменти лише тому, що це нова річ (фрагменти не замінюють діяльність), вам не потрібно використовувати FragmentDialog у випадках, коли цього не виграш. Наприклад, прості сповіщення "Так / Ні".
Renascienza

2
Моя рекомендація: якщо вам потрібно повторно використовувати не просто макет, а фон та код життєвого циклу, використовуйте діалогове вікно «Фрагмент». З фрагментом у вас пов'язаний контроль життєвого циклу діяльності та може реагувати на такі події, як створювати (оскільки інтерфейс користувача створюється заново, коли користувач обертає свій пристрій), робить паузу, відновлення тощо. Якщо цього вам не потрібно, і ваш діалог досить простий, звичайні діалоги справно працюють.
Ренасьєнза

5

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

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

У мене склалося враження, що ОП не хотіла використовувати AlertDialog.Builder. OP Wats щоб знати, чи є метод утиліти швидкого доступу,
walrii

1
Я написав той самий код, але спочатку з'являється НІ, а потім ТАК, в основному це діалогове вікно "НІ / ТАК", але мені потрібне діалогове вікно "ТАК / НІ". Як це зробити
Sagar Devanga

Що стосується ТАК / НІ проти НІ / ТАК, див. Цю відповідь: 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()

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 ), але це дуже корисно для написання більш чистих кодів у будь-якому випадку.


1

Дякую. Я використовую API рівня 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. Клацніть та встановітьOnClickListener ():

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

Примітка. Не забувайте остаточне ключове слово за допомогою 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();  

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

Ви можете зробити це так просто в Котліні:

 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"
  }
})
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.