2010-03-19 11 views
291

Tak, wiem, że istnieje AlertDialog.Builder, ale jestem zszokowany wiedząc, jak trudne (dobrze, przynajmniej nie przyjazne programistom), aby wyświetlić okno dialogowe w systemie Android.Jak wyświetlić okno dialogowe Tak/Nie na Androidzie?

Kiedyś byłem programistą .NET i zastanawiam się, czy istnieje odpowiednik Androida dla następujących elementów?

+0

http://stackoverflow.com/questions/2028697/dialogs-alertdialogs-how-to-block-execution-while-dialog-is-up-net-style?lq=1 – Mertuarez

+1

Jak mogę resue kod AlertDialog i obsługiwać zdarzenia (tak, nie ma akcji) na wszystkich ekranach? W .Net używamy klasy Action do obsługi zdarzeń, czy jest jakiś sposób na jej wdrożenie? Wiem, że używając interfejsów możemy to zrobić, ale w inny alternatywny sposób? – Ravikumar11

+1

Tak ... My, programiści .NET, naprawdę mamy problemy z Androidem ... Ciekawe, czy Xamarin jest świetnym narzędziem? –

Odpowiedz

628

AlertDialog.Builder naprawdę nie jest trudny w użyciu. Na początku jest trochę onieśmielająco, ale kiedy już go użyjesz, będzie to proste i potężne. Wiem, że powiedział, że wie, jak go używać, ale tutaj to tylko prosty przykład, w każdym razie:

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żna również ponowne że DialogInterface.OnClickListener jeśli masz inne Tak/Nie pola, które należy zrobić to samo .

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

+3

new AlertDialog.Builder (this); Błąd czasu kompilacji: "Konstruktor AlertDialog.Builder (nowy widok.OnClickListener() {}) jest niezdefiniowany" –

+0

, jeśli chcę, aby zamknąć to okno dialogowe, co należy napisać pod case DialogInterface.BUTTON_NEGATIVE case. –

+0

@VijayBagul 'dialog.dismiss();' – Tushar

32

Odpowiedź Steve'a H jest na miejscu, ale tutaj jest trochę więcej informacji: powód, dla którego okna dialogowe działają tak, jak robią to dlatego, że dialogi w Androidzie są asynchroniczne (wykonanie nie kończy się, gdy wyświetlane jest okno dialogowe). Z tego powodu musisz użyć wywołania zwrotnego, aby obsłużyć wybór użytkownika.

Sprawdź to pytanie do dłuższej dyskusji pomiędzy różnicami w Androidzie i .NET (dotyczy ona dialogów): Dialogs/AlertDialogs: How to "block execution" while dialog is up (.NET-style)

+8

Dzięki temu fakt, że okna dialogowe Androida są asynchroniczne, sprawia, że ​​wszystko staje się teraz jasne (i rozsądne). Wydaje mi się, że muszę "myśleć z .Net" podczas tworzenia aplikacji dla Androida :) – Solo

+0

FYI: to, co nazywasz "dialogiem asynchronicznym" nazywa się "dialogiem niemodnym" w terminologii GUI, podczas gdy "dialog synchroniczny" nazywa się "dialog modalny" . Android nie ma modalnych okien dialogowych (z wyjątkiem bardzo wyjątkowych przypadków). – Alex

+0

Android nie zezwala na systemowe okna dialogowe z bardzo dobrego powodu: nie może ingerować w inne aplikacje na urządzeniu. – Renascienza

1

Dzięki. Używam API Level 2 (Android 1.1) i zamiast BUTTON_POSITIVE i BUTTON_NEGATIVE muszę używać BUTTON1 i BUTTON2.

108

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

Osobiście podoba mi się ten fragment kodu bardziej niż zaakceptowana odpowiedź: – John

+0

@ nikki dlaczego obaj mają zwolnienie()? – likejiujitsu

+1

To działało lepiej dla mnie, wtedy odpowiedź też – Bob21

5

Dzięki Nikki odpowiedź pomogła mi poprawić istniejący po prostu dodając moje pożądanego działania następująco

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

Mam wrażenie, że OP nie chciał używać AlertDialog.Builder. OP wats, aby wiedzieć, czy istnieje metoda narzędzia skrót, – walrii

+1

Napisałem ten sam kod, ale NIE pojawia się najpierw, a następnie YES zasadniczo jest to okno dialogowe NO/YES, ale potrzebuję okno dialogowe TAK/NIE Jak to zrobić it –

+0

Jeśli chodzi o TAK/NIE, a NIE/TAK, zobacz tę odpowiedź: http://stackoverflow.com/a/13644589/1815624 można manipulować nim tak, jak opisano w tej odpowiedzi: http://stackoverflow.com/a/13644536/1815624 – CrandellWS

4

Steves odpowiedź jest poprawna, choć przestarzały z fragmentów. 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 rozpocząć dialog:

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

Można również pozwolić klasa wdrożenia onClickListener i używać zamiast słuchaczy wbudowanych.

+0

no endTransaction() konieczne? – likejiujitsu

+0

@likejiujitsu powyżej jest wystarczająca. – Warpzit

+0

Utwórz klasę FragmentDialog tylko po to, aby zrobić pole "nie/tak" jest trochę przesadzone ... :) Domyślny AlertDialog jest wystarczająco dobry. – Renascienza

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

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

} 
+0

Dziękuję. To dla mnie praca – kosala

13

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

można zaimplementować rodzajowe rozwiązanie dla decyzji i wykorzystać w innym przypadku nie tylko tak/nie i niestandardowego alertu z animacji lub układ:

Coś takiego; najpierw utworzyć klasę w zakresie danych transferu:

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 zwrotu wynik

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żna utworzyć utils dostępu łatwo (w tej klasie można wdrożyć inną animację lub niestandardowy układ dla 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(); 
    } 
} 

oraz ostatnie wywołanie czynności lub fragmentu; można to wykorzystać w was wypadku lub 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 ... 
      } 
     }; 
    } 
} 
1

Wszystkie tutaj odpowiedzi sprowadzają się do długiej i nie przyjazny dla czytelnika kodu: tylko to, co osoba wnioskująca starał się uniknąć. Dla mnie był najłatwiejszym rozwiązaniem jest zatrudnienie lambdy tutaj:

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 w Androida wymaga wtyczki retrolambda (https://github.com/evant/gradle-retrolambda), ale jest to niezwykle pomocne w pisaniu czystsze kod jakikolwiek.

1

W Kotlin:

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

Pokażokno anonimowo jako łańcuch poleceń & 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(); 
0

1.Create AlertDialog zestaw wiadomości, tytuł i pozytywna, negatywna Przycisk:

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.Na obu przyciskach kliknij DialogInterface Kliknij, a następnie setOnClic kListener():

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.To Pokaż Alertdialog:

alertDialog.show(); 

Uwaga: Nie zapomnij Ostateczne słowo z AlertDialog.

Powiązane problemy