2011-05-26 209 views
59

我想保持我的对话框打开时,我按下按钮。 目前正在关闭。Android对话框,按下按钮时保持对话框打开

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

builder.setMessage("Are you sure you want to exit?") 

    .setCancelable(false) 
    .setPositiveButton("Yes", new DialogInterface.OnClickListener() { 
     public void onClick(DialogInterface dialog, int id) { 
      MyActivity.this.finish(); 
     } 
    }) 
    .setNegativeButton("No", new DialogInterface.OnClickListener() { 
     public void onClick(DialogInterface dialog, int id) { 
      dialog.cancel(); 
     } 
    }); 
AlertDialog alert = builder.create(); 
+4

类似的问题:http://stackoverflow.com/questions/2620444/android-how-to在发送基于响应的登录细节之后,当显示警报并再次询问用户名以确认并确认并取消对话界面按钮时,在登录屏幕上点击 - 预防对话框 - 关闭或者剩余对话框 - 当按钮被点击 – 2012-06-14 16:48:20

+0

时。如果用户没有在对话框中输入任何东西,并点击确定提醒对话框甚至不写我dismiss.once我需要检查验证为空或不是然后才解雇,如果不是空的其他明智的显示seterror上edittext请帮我做不同的方式从最后一天起 – Harsha 2016-07-18 05:35:06

+1

这会更好[禁用按钮,直到用户准备好继续](http://stackoverflow.com/a/40669929/3681880),而不是阻止用户点击按钮后关闭对话框。 – Suragch 2016-11-18 06:14:02

回答

88

是的,你可以。你基本上需要:

  1. DialogBu​​ilder
  2. 显示创建对话框()对话框
  3. 查找所示的对话框中的按钮和覆盖其onClickListener

因此,创建一个听众等级:

class CustomListener implements View.OnClickListener { 
    private final Dialog dialog; 

    public CustomListener(Dialog dialog) { 
    this.dialog = dialog; 
    } 

    @Override 
    public void onClick(View v) { 

    // Do whatever you want here 

    // If you want to close the dialog, uncomment the line below 
    //dialog.dismiss(); 
    } 
} 

然后w母鸡显示对话框使用:

AlertDialog dialog = dialogBuilder.create(); 
dialog.show(); 
Button theButton = dialog.getButton(DialogInterface.BUTTON_POSITIVE); 
theButton.setOnClickListener(new CustomListener(dialog)); 

请记住,您需要显示对话框,否则该按钮将无法找到。此外,请务必将DialogInterface.BUTTON_POSITIVE更改为您用来添加按钮的任何值。另外请注意,当在DialogBu​​ilder中添加按钮时,您将需要提供onClickListeners - 您无法在其中添加自定义侦听器,但是 - 如果在调用show()之后未覆盖侦听器,对话框仍然会消失。

+0

如果它已经存在,他为什么要创建一个自定义侦听器?他只需要做任何他想做的事情“dialog.cancel();”是。 – DallaRosa 2011-05-26 17:14:45

+1

@DallaRosa考察AlertController的实现。 @Sebastian这和我所做的一样,我可以证实卡门的答案有效。 – pawelzieba 2011-05-26 17:23:16

+0

感谢您的好样本,但“私人最终对话框”变量类型应该是AlertDialog而不是Dialog,而且缩览器方法参数也应该是AlertDialog。 – 2014-07-14 10:17:30

0

您可能需要定义自己的布局而不使用“官方”按钮;你所要求的行为并不是典型的对话。

2

这是我如何设法在更改密码时创建持久弹出窗口。

// Login Activity 
AlertDialog.Builder alert = new AlertDialog.Builder(this); 
alert.SetIcon(Resource.Drawable.padlock); 
alert.SetCancelable(false); 

var changepass = LayoutInflater.From(this); 
var changePassLayout = changepass.Inflate(Resource.Layout.ChangePasswordLayout, null); 

alert.SetView(changePassLayout); 

txtChangePassword = (EditText)changePassLayout.FindViewById(Resource.Id.txtChangePassword); 
txtChangeRetypePassword = (EditText)changePassLayout.FindViewById(Resource.Id.txtChangeRetypePassword); 

alert.SetPositiveButton("Change", delegate { 
    // You can leave this blank because you override the OnClick event using your custom listener 
}); 

alert.SetNegativeButton("Cancel", delegate { 
    Toast.MakeText(this, "Change password aborted!", ToastLength.Short).Show(); 
}); 

AlertDialog changePassDialog = alert.Create(); 
changePassDialog.Show(); 

// Override OnClick of Positive Button 
Button btnPositive = changePassDialog.GetButton((int)Android.Content.DialogButtonType.Positive); 
btnPositive.SetOnClickListener(new CustomListener(changePassDialog, empDetailsToValidate.EmployeeID)); 

// My Custom Class 
class CustomListener : Java.Lang.Object, View.IOnClickListener, IDialogInterfaceOnDismissListener 
{ 
    AlertDialog _dialog; 
    EditText txtChangePassword; 
    EditText txtChangeRetypePassword; 

    EmployeeDetails _empDetails; 
    string _workingEmployeeID; 

    public CustomListener(AlertDialog dialog, string employeeID) 
    { 
     this._dialog = dialog; 
     this._workingEmployeeID = employeeID; 
    } 
    public void OnClick (View v) 
    { 
     _empDetails = new EmployeeDetails(v.Context); 

     txtChangePassword = (EditText)_dialog.FindViewById (Resource.Id.txtChangePassword); 
     txtChangeRetypePassword = (EditText)_dialog.FindViewById (Resource.Id.txtChangeRetypePassword); 

     if (!(txtChangePassword.Text.Equals(txtChangeRetypePassword.Text))) { 
      Show(); 
      Toast.MakeText(v.Context, "Password not match.", ToastLength.Short).Show(); 
     } else if (txtChangePassword.Text.Trim().Length < 6) { 
      Show(); 
      Toast.MakeText(v.Context, "Minimum password length is 6 characters.", ToastLength.Short).Show(); 
     } else if ((txtChangePassword.Text.Equals(LoginActivity.defaultPassword)) || (txtChangePassword.Text == "" || txtChangeRetypePassword.Text == "")) { 
      Show(); 
      Toast.MakeText(v.Context, "Invalid password. Please use other password.", ToastLength.Short).Show(); 
     } else { 
      int rowAffected = _empDetails.UpdatePassword(_workingEmployeeID, SensoryDB.PassCrypto(txtChangePassword.Text, true)); 
      if (rowAffected > 0) { 
       Toast.MakeText(v.Context, "Password successfully changed!", ToastLength.Short).Show(); 
       _dialog.Dismiss(); 
      } else { 
       Toast.MakeText(v.Context, "Cant update password!", ToastLength.Short).Show(); 
       Show(); 
      } 
     } 
    } 
    public void OnDismiss (IDialogInterface dialog) 
    { 
     if (!(txtChangePassword.Text.Equals (txtChangePassword.Text))) { 
      Show(); 
     } else { 
      _dialog.Dismiss(); 
     } 
    } 
    public void Show() 
    { 
     _dialog.Show(); 
    } 
} 

BTW,我使用单声道的Android不蚀。

13

我相信@Kamen的答案是正确的,这里是用匿名类,而不是相同的方法的一个例子所以它是所有在一个代码流:

AlertDialog.Builder builder = new AlertDialog.Builder(getActivity()); 
builder.setMessage("Test for preventing dialog close"); 
AlertDialog dialog = builder.create(); 
dialog.show(); 
//Overriding the handler immediately after show is probably a better approach than OnShowListener as described below 
dialog.getButton(AlertDialog.BUTTON_POSITIVE).setOnClickListener(new View.OnClickListener() 
     {    
      @Override 
      public void onClick(View v) 
      { 
       Boolean wantToCloseDialog = false; 
       //Do stuff, possibly set wantToCloseDialog to true then... 
       if(wantToCloseDialog) 
        dismiss(); 
       //else dialog stays open. Make sure you have an obvious way to close the dialog especially if you set cancellable to false. 
      } 
     }); 

我写了一个更详细的写直到回答同样的问题https://stackoverflow.com/a/15619098/579234其中也有其他对话框的例子,如DialogFragment和DialogPreference。

26

感谢Sogger的回答,但是我们必须做一个改变,就是在创建对话框之前,我们应该将AlertDialog设置为传统方式的正号按钮(如果需要,还需要负号按钮),就是这样。

由Sogger引用。

下面是示例例子...

AlertDialog.Builder builder = new AlertDialog.Builder(this); 
     builder.setMessage("Test for preventing dialog close"); 
     builder.setTitle("Test"); 

     builder.setPositiveButton("OK", new OnClickListener() { 

      @Override 
      public void onClick(DialogInterface dialog, int which) { 
       // TODO Auto-generated method stub 

      } 
     }); 
    builder.setNegativeButton("Cancel", new OnClickListener() { 

      @Override 
      public void onClick(DialogInterface dialog, int which) { 
       // TODO Auto-generated method stub 

      } 
     }); 

     final AlertDialog dialog = builder.create(); 
     dialog.show(); 
     //Overriding the handler immediately after show is probably a better approach than OnShowListener as described below 
     dialog.getButton(AlertDialog.BUTTON_POSITIVE).setOnClickListener(new View.OnClickListener() 
       {    
        @Override 
        public void onClick(View v) 
        { 
         Boolean wantToCloseDialog = false; 
         //Do stuff, possibly set wantToCloseDialog to true then... 
         if(wantToCloseDialog) 
          dialog.dismiss(); 
         //else dialog stays open. Make sure you have an obvious way to close the dialog especially if you set cancellable to false. 
        } 
       }); 

     dialog.getButton(AlertDialog.BUTTON_NEGATIVE).setOnClickListener(new View.OnClickListener() 
      {    
       @Override 
       public void onClick(View v) 
       { 
        Boolean wantToCloseDialog = true; 
        //Do stuff, possibly set wantToCloseDialog to true then... 
        if(wantToCloseDialog) 
         dialog.dismiss(); 
        //else dialog stays open. Make sure you have an obvious way to close the dialog especially if you set cancellable to false. 
       } 
      }); 
+0

作为评论或编辑我的答案,这将会更加有用......但我想我的答案与我的回答相比,还是原着的@Kamen解决方案,所以c'est la vie。 – Sogger 2015-01-23 23:33:42

+0

@Sogger对不起,我并不想伤害你,但是当时我在更新时使用了stackoverflow。但是,正如我在答复开始时宣布的那样,这个答案是献给你的。德索莱。 – Shailesh 2016-11-10 11:36:02

0

你可以得到该对话框的方法 “秀()” alertBuidler返回。

AlertDialog.Builder adb = new AlertDialog.Builder(YourActivity.this); 
//...code to add methods setPositive an setNegative buttons 

呼叫“显示()”的“亚行”的方法,并得到对话框

final AlertDialog dialog = adb.show(); 

所以,你可以在你的活动在代码的任何地方调用你的对话框中的任意按钮:

dialog.getButton(DialogInterface.BUTTON_POSITIVE).performClick();//or 
dialog.getButton(DialogInterface.BUTTON_NEGATIVE).performClick();//or 
dialog.getButton(DialogInterface.BUTTON_NEUTRAL).performClick(); 
0

您不需要创建自定义类。您可以为AlertDialog注册一个View.OnClickListener。这个监听器不会关闭AlertDialog。这里的诀窍是你需要在显示对话框后注册监听器,但是它可以在OnShowListener中完成。您可以使用附件布尔变量来检查,如果这已经这样做了,它只会做一次:

/* 
* Prepare the alert with a Builder. 
*/ 
AlertDialog.Builder b = new AlertDialog.Builder(this); 

b.setNegativeButton("Button", new DialogInterface.OnClickListener() { 
    @Override 
    public void onClick(DialogInterface dialog, int which) {} 
}); 
this.alert = b.create(); 

/* 
* Add an OnShowListener to change the OnClickListener on the 
* first time the alert is shown. Calling getButton() before 
* the alert is shown will return null. Then use a regular 
* View.OnClickListener for the button, which will not 
* dismiss the AlertDialog after it has been called. 
*/ 

this.alertReady = false; 
alert.setOnShowListener(new DialogInterface.OnShowListener() { 
    @Override 
    public void onShow(DialogInterface dialog) { 
     if (alertReady == false) { 
      Button button = alert.getButton(DialogInterface.BUTTON_NEGATIVE); 
      button.setOnClickListener(new View.OnClickListener() { 
       @Override 
       public void onClick(View v) { 
        //do something 
       } 
      }); 
      alertReady = true; 
     } 
    } 
});