来自.NET环境我现在正在寻找了解Dialog如何在Android中运行的方法.
在.NET中,调用MessageBox.Show(...)创建并显示弹出对话框.在对Show的调用中,我可以指定弹出窗口中应该有哪些按钮,例如:
DialogResult myDialogResult = MessageBox.Show("My text here", "My caption here", MessageBoxButtons.YesNoCancel);
Run Code Online (Sandbox Code Playgroud)
正如您所看到的,当在弹出窗口中按下按钮时,对Show的调用将返回一个DialogResult,通知我单击了哪个按钮.请注意,在.NET中,执行将在调用Show(...)的行中停止,因此它可以在按下按钮时返回值.
如果我在上面的例子中按"否",则myDialogResult将等于
myDialogResult == DialogResult.No
Run Code Online (Sandbox Code Playgroud)
由于我发现使用/创建弹出窗口的.NET方式非常简单直观,我想在Android中创建弹出窗口的方式.
所以,问题是,是否有人知道如何"停止执行",如MessageBox.Show,然后每按一次按钮返回一个值(对话框消失)?
问候
编辑1: 更清楚一点:
我需要执行停止并等到用户选择了一个按钮来单击弹出窗口.显示对话框的调用后面的代码取决于在对话框中单击的按钮.
这就是为什么我不能使用Erich和Alex所建议的,因为在下面建议的onClick方法中编写代码是行不通的.原因是我无法继续"正常执行".让我举一个例子:
让我举一个例子:
int nextStep = 0; // this variable will not be reached from within the onClick-methods
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setMessage("Hello!")
.setPositiveButton("Ok", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
nextStep = 1; // *** COMPILER ERROR!! ***
}
})
.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
nextStep = 2; // *** COMPILER ERROR!! ***
}
})
.create().show();
if (nextStep == 1)
{
// then do some damage
}
else if (nextStep == 2
// dont do damage
Run Code Online (Sandbox Code Playgroud)
如果我希望执行依赖于弹出窗口中的选择,我会以某种方式使onClick方法中的"正常执行"(在本例中为nextStep)中的所有变量都可用,这对我来说听起来很糟糕.
编辑2:
另一个明显的例子是弹出窗口,询问"你想继续"选项"是"和"否".
如果用户按"是",则应中止整个方法,否则应继续执行.你怎么解决这个问题呢?
问候
Rom*_*Guy 47
Ted,你不想这样做,真的:)最大的原因是如果你在显示一个Dialog时阻止UI线程,你将阻止负责绘制和处理Dialog事件的线程.这意味着您的对话框将无响应.如果用户单击对话框需要几秒钟,您还将导致ANR.
Erich的答案正是您所需要的.我知道这不是你想要的,但这并不重要.我们设计了Android以防止开发人员编写同步对话框,因此您没有太多选择.
Eri*_*ass 19
在Android中,结构与.NET不同:
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setMessage("Hello!")
.setPositiveButton("Ok", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
// Handle Ok
}
})
.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
// Handle Cancel
}
})
.create();
Run Code Online (Sandbox Code Playgroud)
将为您提供一个带有两个按钮的对话框,您可以使用回调来处理按钮单击.您可能能够编写一些代码来使语法更接近.NET,但是对话框生命周期非常紧密Activity,因此最终可能比它的价值更麻烦.其他对话框引用在这里.
Min*_*ker 19
Daniel上面的答案的简化版本.此函数在警告对话框中从用户获得"是"或"否",但可以轻松修改以获取其他输入.
private boolean mResult;
public boolean getYesNoWithExecutionStop(String title, String message, Context context) {
// make a handler that throws a runtime exception when a message is received
final Handler handler = new Handler() {
@Override
public void handleMessage(Message mesg) {
throw new RuntimeException();
}
};
// make a text input dialog and show it
AlertDialog.Builder alert = new AlertDialog.Builder(context);
alert.setTitle(title);
alert.setMessage(message);
alert.setPositiveButton("Yes", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
mResult = true;
handler.sendMessage(handler.obtainMessage());
}
});
alert.setNegativeButton("No", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
mResult = false;
handler.sendMessage(handler.obtainMessage());
}
});
alert.show();
// loop till a runtime exception is triggered.
try { Looper.loop(); }
catch(RuntimeException e2) {}
return mResult;
}
Run Code Online (Sandbox Code Playgroud)
Dav*_*ebb 11
在Android中,Dialogs是异步的,因此您将不得不以不同的方式构建代码.
所以在C#中你的逻辑在伪代码中运行了类似的东西:
void doSomeStuff() {
int result = showDialog("Pick Yes or No");
if (result == YES) {
//do stuff for yes
}
else if (result == NO) {
//do stuff for no
}
//finish off here
}
Run Code Online (Sandbox Code Playgroud)
对于Android来说,它必须不那么整洁.想想就好.你会有OnClickListener这样的:
public void onClick(DialogInterface dialog, int whichButton) {
if (whichButton == BUTTON_POSITIVE) {
doOptionYes();
}
else if (whichButton == BUTTON_NEGATIVE) {
doOptionNo();
}
}
Run Code Online (Sandbox Code Playgroud)
然后由以下方法支持:
void doOptionYes() {
//do stuff for yes
endThings();
}
void doOptionNo() {
//do stuff for no
endThings();
}
void endThings() {
//clean up here
}
Run Code Online (Sandbox Code Playgroud)
那么一种方法现在是四种.它可能看起来不是很整洁,但我担心它的工作方式.
PasswordDialog dlg = new PasswordDialog(this);
if(dlg.showDialog() == DialogResult.OK)
{
//blabla, anything your self
}
public class PasswordDialog extends Dialog
{
int dialogResult;
Handler mHandler ;
public PasswordDialog(Activity context, String mailName, boolean retry)
{
super(context);
setOwnerActivity(context);
onCreate();
TextView promptLbl = (TextView) findViewById(R.id.promptLbl);
promptLbl.setText("Input password/n" + mailName);
}
public int getDialogResult()
{
return dialogResult;
}
public void setDialogResult(int dialogResult)
{
this.dialogResult = dialogResult;
}
/** Called when the activity is first created. */
public void onCreate() {
setContentView(R.layout.password_dialog);
findViewById(R.id.cancelBtn).setOnClickListener(new android.view.View.OnClickListener() {
@Override
public void onClick(View paramView)
{
endDialog(DialogResult.CANCEL);
}
});
findViewById(R.id.okBtn).setOnClickListener(new android.view.View.OnClickListener() {
@Override
public void onClick(View paramView)
{
endDialog(DialogResult.OK);
}
});
}
public void endDialog(int result)
{
dismiss();
setDialogResult(result);
Message m = mHandler.obtainMessage();
mHandler.sendMessage(m);
}
public int showDialog()
{
mHandler = new Handler() {
@Override
public void handleMessage(Message mesg) {
// process incoming messages here
//super.handleMessage(msg);
throw new RuntimeException();
}
};
super.show();
try {
Looper.getMainLooper().loop();
}
catch(RuntimeException e2)
{
}
return dialogResult;
}
}
Run Code Online (Sandbox Code Playgroud)
在Android中尝试优化内存和性能对话框是异步的(它们也因此而受到管理).来自Windows世界,您习惯于模态对话框.Android对话框是模态的,但在执行时更像非模态.显示对话框后,执行不会停止.
我见过的Android中Dialogs的最佳描述是在"Pro Android"中http://www.apress.com/book/view/1430215968
这不是一个完美的解释,但它可以帮助您围绕Windows和Android中的Dialogs之间的差异.在Windows中你想做A,用对话框问一个问题,然后做B或C.在android设计中,你需要在OnClickListener的onClick()中为B和C所需的所有代码用于对话框.然后执行A并启动对话框.你完成了A!当用户点击按钮时,B或C将被执行.
Windows
-------
A code
launch dialog
user picks B or C
B or C code
done!
Android
-------
OnClick for B code (does not get executed yet)
OnClick for C code (does not get executed yet)
A code
launch dialog
done!
user picks B or C
Run Code Online (Sandbox Code Playgroud)
Android和iOS的开发人员认为他们是强大而聪明的,足以拒绝Modal Dialog概念(这已经在市场上存在很多年了,之前并没有打扰过任何人),不幸的是我们.我相信有解决Android的 - 因为你可以使用Runnable接口类显示来自非UI线程对话,应该有一种方法在该线程(非UI)要等到对话结束.
编辑:这是我的解决方案,效果很好:
int pressedButtonID;
private final Semaphore dialogSemaphore = new Semaphore(0, true);
final Runnable mMyDialog = new Runnable()
{
public void run()
{
AlertDialog errorDialog = new AlertDialog.Builder( [your activity object here] ).create();
errorDialog.setMessage("My dialog!");
errorDialog.setButton("My Button1", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
pressedButtonID = MY_BUTTON_ID1;
dialogSemaphore.release();
}
});
errorDialog.setButton2("My Button2", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
pressedButtonID = MY_BUTTON_ID2;
dialogSemaphore.release();
}
});
errorDialog.setCancelable(false);
errorDialog.show();
}
};
public int ShowMyModalDialog() //should be called from non-UI thread
{
pressedButtonID = MY_BUTTON_INVALID_ID;
runOnUiThread(mMyDialog);
try
{
dialogSemaphore.acquire();
}
catch (InterruptedException e)
{
}
return pressedButtonID;
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
96080 次 |
| 最近记录: |