从复杂的自定义对话框(例如,文本字段,日期或时间选择器,一堆单选按钮等)以及"保存"和"取消"按钮将值返回到调用活动的"正确"方法是什么?
我在网上看到的一些技术包括:
Dialog派生类中的公共数据成员,可以由Activity读取
公共"获取"访问者..."......" ."
有意向启动的对话框(而不是显示() ),加上在对话框类处理它采取从各种控制输入和捆绑起来传递回活动,所以当听众打"保存"捆绑传回使用 ReturnIntent()
Activity中的监听器处理对话框中控件的输入,例如,TimePicker或DatePicker的监听器实际上在Activity中.在这个方案中,几乎所有的工作都在活动中完成
"活动"中的一个监听器为"保存"按钮,然后活动直接询问对话框中的控件; 活动解除了对话框.
......加上我已经忘记的更多.
是否有一种被认为是规范正确或"最佳实践"方法的特定技术?
Com*_*ish 20
也许我误解了你的问题,但为什么不使用内置的监听系统:
builder.setPositiveButton("Yes", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
// run whatever code you want to run here
// if you need to pass data back, just call a function in your
// activity and pass it some parameters
}
})
Run Code Online (Sandbox Code Playgroud)
这就是我总是处理对话框中的数据的方式.
编辑:让我给你一个更具体的例子,它将更好地回答你的问题.我要从这个页面窃取一些示例代码,您应该阅读:
http://developer.android.com/guide/topics/ui/dialogs.html
// Alert Dialog code (mostly copied from the Android docs
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle("Pick a color");
builder.setItems(items, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int item) {
myFunction(item);
}
});
AlertDialog alert = builder.create();
Run Code Online (Sandbox Code Playgroud)
...
// Now elsewhere in your Activity class, you would have this function
private void myFunction(int result){
// Now the data has been "returned" (as pointed out, that's not
// the right terminology)
}
Run Code Online (Sandbox Code Playgroud)
小智 7
对于我的MIDI应用程序,我需要是/否/取消确认对话框,所以我首先制作了一般的StandardDialog类:
public class StandardDialog {
import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.os.Handler;
public class StandardDialog {
public static final int dlgResultOk = 0;
public static final int dlgResultYes = 1;
public static final int dlgResultNo = 2;
public static final int dlgResultCancel = 3;
public static final int dlgTypeOk = 10;
public static final int dlgTypeYesNo = 11;
public static final int dlgTypeYesNoCancel = 12;
private Handler mResponseHandler;
private AlertDialog.Builder mDialogBuilder;
private int mDialogId;
public StandardDialog(Activity parent,
Handler reponseHandler,
String title,
String message,
int dialogType,
int dialogId) {
mResponseHandler = reponseHandler;
mDialogId = dialogId;
mDialogBuilder = new AlertDialog.Builder(parent);
mDialogBuilder.setCancelable(false);
mDialogBuilder.setTitle(title);
mDialogBuilder.setIcon(android.R.drawable.ic_dialog_alert);
mDialogBuilder.setMessage(message);
switch (dialogType) {
case dlgTypeOk:
mDialogBuilder.setNeutralButton("Ok", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
mResponseHandler.sendEmptyMessage(mDialogId + dlgResultOk);
}
});
break;
case dlgTypeYesNo:
case dlgTypeYesNoCancel:
mDialogBuilder.setPositiveButton("Yes", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
mResponseHandler.sendEmptyMessage(mDialogId + dlgResultYes);
}
});
mDialogBuilder.setNegativeButton("No", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
mResponseHandler.sendEmptyMessage(mDialogId + dlgResultNo);
}
});
if (dialogType == dlgTypeYesNoCancel) {
mDialogBuilder.setNeutralButton("Cancel", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
mResponseHandler.sendEmptyMessage(mDialogId + dlgResultCancel);
}
});
}
break;
}
mDialogBuilder.show();
}
}
Run Code Online (Sandbox Code Playgroud)
接下来,在我的主要活动中,我已经有来自其他线程的UI更新的消息处理程序,所以我只是添加了用于处理来自对话框的消息的代码.通过在我为各种程序函数实例化StandardDialog时使用不同的dialogId参数,我可以执行正确的代码来处理对不同问题的是/否/取消响应.这个想法可以通过发送数据包扩展到复杂的自定义对话框,虽然这比简单的整数消息要慢得多.
private Handler uiMsgHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
if (msg != null) {
// {Code to check for other UI messages here}
// Check for dialog box responses
if (msg.what == (clearDlgId + StandardDialog.dlgResultYes)) {
doClearDlgYesClicked();
}
else if (msg.what == (recordDlgId + StandardDialog.dlgResultYes)) {
doRecordDlgYesClicked();
}
else if (msg.what == (recordDlgId + StandardDialog.dlgResultNo)) {
doRecordDlgNoClicked();
}
}
}
};
Run Code Online (Sandbox Code Playgroud)
然后我需要做的就是在活动中定义do {Whatever}()方法.为了调出一个对话框,作为一个例子,我有一个方法响应"清除记录的MIDI事件"按钮并确认如下:
public void onClearBtnClicked(View view) {
new StandardDialog(this, uiMsgHandler,
getResources().getString(R.string.dlgTitleClear),
getResources().getString(R.string.dlgMsgClear),
StandardDialog.dlgTypeYesNo, clearDlgId);
}
Run Code Online (Sandbox Code Playgroud)
clearDlgId在其他地方被定义为唯一的整数.此方法在活动前面弹出"是/否"对话框,在对话框关闭之前会丢失焦点,此时活动会收到带有对话框结果的消息.然后,doClearDlgYesClicked()如果单击"是"按钮,则消息处理程序将调用该方法.(我不需要"否"按钮的消息,因为在那种情况下不需要采取任何行动).
无论如何,这种方法对我有用,并且可以很容易地从对话框中传回结果.
我正在使用以下方式:
private volatile Bundle controlBundle;适当的 getter/setter当我开始对话时,我曾经通过我自己的方法调用对话:
public void showMyDialog(int id, Bundle bundle)
{
this.controlBundle=bundle;
this.showDialog(id, bundle);
}
Run Code Online (Sandbox Code Playgroud)所以每次我知道参数发送到对话框
Bundle具有必要值的对话,然后将它们通过我的Activity捆绑设置器:
((ControlActivity )this.getOwnerActivity).setControlBundle(bundle);
Run Code Online (Sandbox Code Playgroud)
所以最后当对话框结束时,我知道从对话框“返回”的值。我知道这并不int retCode=this.showMyDialog();复杂,但它是可行的。