我想创建一个带有文本字段和按钮的dialogBuilder。我们的想法是让程序等待任何进一步的操作,直到输入字段中的文本并单击确定按钮。以下是代码:
private static final Object wait = new int[0];
private static String result = null;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Handler h = new Handler();
final Context context = MainActivity.this;
h.post(new Runnable() {
public void run() {
final Builder dialogBuilder = new AlertDialog.Builder(context);
dialogBuilder.setTitle(R.string.app_name);
final LinearLayout panel = new LinearLayout(context);
panel.setOrientation(LinearLayout.VERTICAL);
final TextView label = new TextView(context);
label.setId(1);
label.setText(R.string.app_name);
panel.addView(label);
final EditText input = new EditText(context);
input.setId(2);
input.setSingleLine();
input.setInputType(InputType.TYPE_CLASS_TEXT
| InputType.TYPE_TEXT_VARIATION_URI
| InputType.TYPE_TEXT_VARIATION_PHONETIC);
final ScrollView view = new ScrollView(context);
panel.addView(input);
view.addView(panel);
dialogBuilder
.setCancelable(true)
.setPositiveButton(R.string.app_name,
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog,
int id) {
result = input.getText().toString();
synchronized (wait) {
wait.notifyAll();
}
dialog.dismiss();
}
}).setView(view);
dialogBuilder.setOnCancelListener(new OnCancelListener() {
public void onCancel(DialogInterface arg0) {
result = null;
synchronized (wait) {
wait.notifyAll();
}
}
});
dialogBuilder.create().show();
}
});
String localResult = null;
try {
synchronized (wait) {
Log.d("Waiting", "Waiting " + localResult);
wait.wait();
}
localResult = result;
result = null;
if (localResult == null) {
// user is requesting cancel
throw new RuntimeException("Cancelled by user");
}
Log.d("RESULT ", "RESULT " + localResult);
} catch (InterruptedException e) {
localResult = result;
result = null;
if (localResult == null) {
// user is requesting cancel
Log.d("CANCELED ", "CANCELED " + localResult);
throw new RuntimeException("Cancelled by user");
}
}
Log.d("RESULT AFTER THE DIALOG", "RESULT AFTER THE DIALOG " + result);
}
该程序将进入Log.d(“Waiting”,“Waiting”+ localResult);然后等待。活动窗口上没有DIALOG BUILDER。我使用了调试模式,发现程序流没有进入run()方法,但Handler.post()的值为true。因此,对话框未显示,程序正在等待。
我试图删除等待的时刻(删除Handler.post()),只是为了看对话框是否显示,它显示并且一切都很好,但结果不是我需要的 - 我想要等待对话输入的程序......我真的没有想法。
请你给我一些建议,因为我真的没有想法。
非常感谢!
答案 0 :(得分:1)
Handlers
不在单独的线程中运行。所以当你致电wait()
时:
synchronized (wait) {
Log.d("Waiting", "Waiting " + localResult);
wait.wait();
}
它无限期地等待,因为处理程序在与当前线程相同的线程上运行。您的Runnable
只能在onCreate()
方法完成后执行,但由于您刚刚调用wait()
,因此永远不会发生此事。
您应该重新考虑您的想法并找到解决方法(例如,只要用户没有输入有效的文本,就会以通常的方式显示对话框并禁用“确定”按钮)。但是在UI线程上调用wait()
可能不顺利。
答案 1 :(得分:0)
您应该在UI线程中运行Dialog的显示,而不是单独的线程。
一个例子是这样的:
runOnUiThread(new Runnable() {
@Override
public void run() {
// Display progress dialog when loading contacts
dialog = new ProgressDialog(this);
// continue with config of Dialog
}
});
// Execute the Asynchronus Task
new AsyncTask<Void, Void, Void>() {
@Override
protected Void doInBackground(Void... params) {
// code to execute in background
return null;
}
@Override
protected void onPostExecute(Void result) {
// Dismiss the dialog after inBackground is done
if (dialog != null)
dialog.dismiss();
super.onPostExecute(result);
}
}.execute((Void[]) null);
具体来说,这里发生的是Dialog正在UI线程上显示,然后在Dialog运行时AsyncTask在后台执行。然后在执行结束时我们关闭对话框。