I am trying to show a messagebox with OK button. I am using AlertDialog for this purpose and I realised that it is not blocking the code. Example:
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
new AlertDialog.Builder(this).setTitle("Test dlg").setMessage("Alert 1")
.setPositiveButton("OK", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {}
})
.setNegativeButton("", null)
.show();
new AlertDialog.Builder(this).setTitle("Test dlg").setMessage("Alert 2")
.setPositiveButton("OK", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {}
})
.setNegativeButton("", null)
.show();
//...continue with UI initialization here...
}
When I start activity, it shows Alert2, When I press ok it shows Alert1 afterwards.
I need to have blocking code dialog, so at first it should show Alert1 message, wait until user presses OK button then continue to execute the code and show Alert2 message, etc.. Example:
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
msgBox("Test dlg", "Alert 1");
msgBox("Test dlg", "Alert 2");
//...continue with UI initialization here...
}
private void msgBox(String title, String msg){
//?????
/* WRONG, NON-BLOCKING
new AlertDialog.Builder(this).setTitle(title).setMessage(msg)
.setPositiveButton("OK", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {}
})
.setNegativeButton("", null)
.show();
*/
}
What should I write on //????? place in msgBox method?
MORE EXAMPLE, I need something like this:
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (isInitialisationDataFailed()){
msgBox("Alert", "Cannot open activity, sorry");
myActivity.this.finish();
return;
}
}
But this does not work. Activity finish runs quicker than alert appear on the screen.
The main idea to have messagebox code separate to own method to make it reusable. How to achieve this?
///////////////////////////////// another example:
private void init(){
//init code here...
if (isSomethingWhrong()){
msgbox("wrong stuff will be fixed");
//do fix wrong stuff here...
}
if (isAnotherthingWrong()){
msgbox("more wrong stuff will be fixed");
//do fix more wrong stuff....
}
//continue init code here...
}
private void msgbox(String msg){
//BLOCKING DIALOG REALISATION here...
}
and as alternative this:
private void init(){
//init code here...
handleWrongStuff();
}
private void handleWrongStuff(){
if (isSomethingWhrong()){
new AlertDialog.Builder(activity)
.setTitle("Test")
.setMessage("wrong stuff will be fixed")
.setPositiveButton("OK", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
//do fix wrong stuff here...
handleMoreWrongStuff();
}
})
.setNegativeButton("", null)
.show();
}
else{
handleMoreWrongStuff();
}
}
private void handleMoreWrongStuff(){
if (isAnotherthingWrong()){
new AlertDialog.Builder(activity)
.setTitle("Test")
.setMessage("more wrong stuff will be fixed")
.setPositiveButton("OK", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
//do fix more wrong stuff here...
continueInit();
}
})
.setNegativeButton("", null)
.show();
}
else{
continueInit();
}
}
private void continueInit(){
//continue init code here...
}
do you see the difference in complexity? In order to ma开发者_如何学JAVAke init code working in Android I need to split it to separate methods but not on logical blocks but when I need to show dialogs. Moreover the code for initialization dialogs are repeated and became ugly and unreadable.
Put the code to show 2nd dialog in onClick of Positive button of First alert dialog.
using this way you can't stop the execution but instead of this you can put on button action listener so when button pressed at that time listener will be invoked and you can execute the code for e.g. in your case when you press the ok button then show the next alert from listener.
new AlertDialog.Builder(this).setTitle("Test dlg").setMessage("Alert 1")
.setPositiveButton("OK", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
new AlertDialog.Builder(YourActivity.this).setTitle("Test dlg").setMessage("Alert 2")
.setPositiveButton("OK", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {}
})
.setNegativeButton("", null)
.show();
}
})
.setNegativeButton("", null)
.show();
Dialogs do not block code execution - pretty simple. The only way to achieve a "block-like" behaviour is to split execution-chain into smaller bits.
Lets assume you want to show a total of five Dialogs during UI-initialization. In your Activity, you create the following methods:
private void beforeFirstDialog() {
// Do the initialization until you want the first dialog
// Show the first dialog
// When clicking 'OK' in the first dialog, beforeSecondDialog() is called.
}
private void beforeSecondDialog() {
// Do the initialization until you want the second dialog
// Show the second dialog
// When clicking 'OK' in the second dialog, beforeThirdDialog() is called.
}
private void beforeThirdDialog() {
// Do the initialization until you want the third dialog
// Show the third dialog
// When clicking 'OK' in the third dialog, beforeFourthDialog() is called.
}
private void beforeFourthDialog() {
// Do the initialization until you want the fourth dialog
// Show the fourth dialog
// When clicking 'OK' in the first dialog, beforeFifthDialog() is called.
}
private void beforeFifthDialog() {
// Do the initialization until you want the fifth dialog
// Show the fifth dialog
// When clicking 'OK' in the first dialog, afterFifthDialog() is called.
}
private void afterFifthDialog() {
// Do what needs to be done after the last dialog.
}
This is a late answer, but may give you closure.
The cleanest way to do what you want is to launch an activity instead of the dialog. A simple activity with just one OK button.
When the OK button is pressed just close the activity.
If you need more complex responses, more buttons, text input, etc.
use StartActivityWithResult() to return the user's choice
under the conditon give this.
ShowAlert.displayAlert(the present class name.this,"Please enter the error message");
strDomain.requestFocus();
create a new class ShowAlert, inside that put this code.
public class ShowAlert {
public static void displayAlert(Activity act,String msg)
{
AlertDialog.Builder alert = new AlertDialog.Builder(act);
alert.setMessage(msg).setPositiveButton("OK", new DialogInterface.OnClickListener(){
@Override
public void onClick(DialogInterface dialog, int which)
{
}
})
.show();
}
}
EditText strDomain;
strDomain is the edittext name. it like when that field is null i have made it like unless it is filled it will not go to the next page.. what is your case when you want to show the message at want instance?
As you (might have) discovered from the many replies that you should not block the Main UI
Thread
. However, if you have a very good reason to block the code while you get a response
from the user, then you could create a thread where you loop/wait for the user input while you the AlertDialog
is displayed via the MainUI
Thread
. I have a full blog post here that explains this
protected void RunConfirmAction(Action runnableAction)
{
var confirmThread = new Thread(() => runnableAction());
confirmThread.Start();
}
// OnClick (when the user clicks Logout Button, I call this
RunConfirmAction(Logout);
// the implemtation of the MessageBox waiting looks like this:
public DialogResult MessageBoxShow(string message, string caption, MessageBoxButtons buttons, MessageBoxIcon icon, MessageBoxDefaultButton defaultButton)
{
if (_CurrentContext != null && MainActivity != null)
{
Action<bool> callback = OnConfirmCallBack;
_IsCurrentlyInConfirmProcess = true;
Action messageBoxDelegate = () => MessageBox.Show(((Activity)MainActivity), callback, message, caption, buttons);
RunOnMainUiThread(messageBoxDelegate);
while (_IsCurrentlyInConfirmProcess)
{
Thread.Sleep(1000);
}
}
return _ConfirmBoxResult ? DialogResult.OK : DialogResult.No;
}
private void OnConfirmCallBack(bool confirmResult)
{
_ConfirmBoxResult = confirmResult;
_IsCurrentlyInConfirmProcess = false;
}
private bool _ConfirmBoxResult = false;
private bool _IsCurrentlyInConfirmProcess = false;
I hope this can help somebody, the full details of the solution can be found here
Kotlin makes life easy, call within a co-routine
suspendCoroutine<Context> { cont ->
runOnUiThread {
val builder = androidx.appcompat.app.AlertDialog.Builder(this@YourScreen)
builder.setTitle("Title")
builder.setMessage("I have a message for you")
builder.setPositiveButton("Yes") { _, _ ->
/* Do something on yes */
}
builder.setNegativeButton("No") { _, _ ->
/* Do something on no */
}
builder.setOnCancelListener {
cont.resume(this@YourScreen)
}
val askdialog = builder.create()
askdialog.show()
}
}
//Code will continue here
精彩评论