我的Android应用程序中有操作栏下拉列表。当用户从下拉列表中单击某个项目时。我添加了一个AlertDialogBuilder
来获取用户的一些用户数据,如果用户按下确定,它将保存数据。当我运行代码时,我得到了这个例外。
这是我正在使用的代码
@Override
public boolean onNavigationItemSelected(final int i, long l) {
final ArrayList<Host> hosts = HostFactory.getHosts(this.getApplicationContext());
// get prompts.xml view
LayoutInflater li = LayoutInflater.from(this);
View promptsView = li.inflate(R.layout.auto_discovery_prompt, null);
AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(
this);
// set prompts.xml to alertdialog builder
alertDialogBuilder.setView(promptsView);
final EditText txtDeviceName = (EditText) promptsView.findViewById(R.id.txtdevicename_editTextDialogUserInput);
final EditText txtUsername = (EditText) promptsView.findViewById(R.id.txtusername_editTextDialogUserInput);
final EditText txtPassword = (EditText) promptsView.findViewById(R.id.txtpassword_editTextDialogUserInput);
final EditText txtPort = (EditText) promptsView.findViewById(R.id.txtport_editTextDialogUserInput);
String mac=navSpinner.get(i).getMacaddress();
txtDeviceName.setText(navSpinner.get(i).getTitle());
txtPort.setText(navSpinner.get(i).getPort());
for(SpinnerNavItem items:navSpinner)
{
if(items.getTitle().toString()!="Select your Device" )
{
// set dialog message
alertDialogBuilder
.setCancelable(false)
.setPositiveButton("OK",
new DialogInterface.OnClickListener() {
@TargetApi(Build.VERSION_CODES.GINGERBREAD)
public void onClick(DialogInterface dialog,
int id) {
// get user input and set it to result
// edit text
//result.setText(userInput.getText());
String dd=txtPassword.getText().toString();
Host savecurrent_selected_host =new Host();
savecurrent_selected_host.name=txtDeviceName.getText().toString();
savecurrent_selected_host.addr=navSpinner.get(i).getIPaddress().toString();
try {
savecurrent_selected_host.port = Integer.parseInt(txtPort.getText().toString());
} catch (NumberFormatException e) {
savecurrent_selected_host.port = Host.DEFAULT_HTTP_PORT;
}
savecurrent_selected_host.user=txtUsername.getText().toString();
savecurrent_selected_host.pass=txtPassword.getText().toString();
savecurrent_selected_host.esPort = Host.DEFAULT_EVENTSERVER_PORT;
savecurrent_selected_host.timeout = Host.DEFAULT_TIMEOUT;
savecurrent_selected_host.access_point="";
if(!(navSpinner.isEmpty()&& navSpinner.get(i).getMacaddress().toString().isEmpty()))
savecurrent_selected_host.mac_addr=navSpinner.get(i).getMacaddress().toString();
else
savecurrent_selected_host.mac_addr="";
savecurrent_selected_host.wol_port = Host.DEFAULT_WOL_PORT;
savecurrent_selected_host.wol_wait = Host.DEFAULT_WOL_WAIT;
HostFactory.addHost(getApplicationContext(), savecurrent_selected_host);
HostFactory.saveHost(getApplicationContext(),savecurrent_selected_host);
}
})
.setNegativeButton("Cancel",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog,
int id) {
dialog.cancel();
}
});
// create alert dialog
alertDialog = alertDialogBuilder.create();
// show it
if(!alertDialog.isShowing())
alertDialog.show();
}
}
如何解决这个问题?(来到alertDialog.show()
时应用程序正在制动
答案 0 :(得分:1)
我相信您的代码存在两个问题,第一个问题是导致第二个问题。第一个问题是,您要为alertDialog
中的每个项目显示新的navSpinner
。以下if
声明
if(items.getTitle().toString()!="Select your Device" )
始终为true
,因为您正在进行参考比较(==
)。您想使用.equals()
。 (有关更好的解释,请参阅here。)
if(!items.getTitle().toString().equals("Select your Device" ))
即使这看起来有点可疑,因为您可能希望将循环项目与所选项目进行比较,而不是某些默认字符串。无论如何,因此,您为每个循环迭代创建一个新的alertDialog
alertDialog = alertDialogBuilder.create();
create()
每次都会返回新对话框,因此请进行以下检查
if(!alertDialog.isShowing())
总是true
,因为上面创建的一行 new 对话框显然尚未显示。这意味着新的alertDialog
始终显示
alertDialog.show();
乍一看,您可能希望这会导致显示多个警报对话框,循环中的每个项目都会显示一个。但是,情况并非如此,因为第二个警报对话框 - 将在循环的第二次迭代期间创建 - 将导致IllegalStateException
。为什么?因此:
alertDialogBuilder.setView(promptsView);
虽然您的第二个对话框确实是它自己的对话框,但它与第一个循环迭代期间创建的对话框共享promptsView
。调用show()
时,promptsView
会获得父级。显示第一个对话框时,这是正常的,因为promptsView
是没有指定父级的新视图。但是,当第二个对话框显示时 - 从第二个循环迭代 - show()
方法尝试给promptsView
一个父级,但这次它失败了,因为它已经从第一个对话框中获得了父级show()
。因此错误:指定的孩子已经有父母
简而言之,修复你的循环,这样只显示一个对话框,你应该好好去。