通过AlertDialog向自定义数组适配器添加对象遇空指针异常求助
解决AlertDialog中EditText空指针异常的问题
你碰到的这个java.lang.NullPointerException问题很典型,根源出在你过早地从还未关联布局的AlertDialog对象中查找控件了。
看你setAddingDialog()方法里的这段代码:
Dialog alertDialog = builder.create(); final EditText clientName = (EditText) alertDialog.findViewById(R.id.newClientName); // ... 之后才给builder设置布局并显示对话框
刚创建出来的alertDialog还没有和你写的dialog_add_new_client.xml布局绑定,这时候调用findViewById返回的肯定是null,等你点击"add"按钮调用getText()时,自然就触发空指针异常了。
下面给你两种可行的解决办法:
方案一:直接从Inflate好的布局视图中查找控件(推荐)
先把对话框的布局文件inflate成View对象,然后直接从这个View里找EditText,这样就完全避开了Dialog未绑定布局的问题:
void setAddingDialog(){ AlertDialog.Builder builder = new AlertDialog.Builder(this); LayoutInflater inflater = getLayoutInflater(); // 先加载对话框布局,得到根视图 View dialogRootView = inflater.inflate(R.layout.dialog_add_new_client, null); // 从根视图中获取所有EditText控件 final EditText clientName = dialogRootView.findViewById(R.id.newClientName); final EditText clientId = dialogRootView.findViewById(R.id.newClientId); final EditText clientWallet = dialogRootView.findViewById(R.id.newClientWallet); final EditText clientBalance = dialogRootView.findViewById(R.id.newClientBalance); builder.setView(dialogRootView) .setPositiveButton("add", new DialogInterface.OnClickListener(){ @Override public void onClick(DialogInterface dialogInterface, int i) { // 获取输入内容 String nameValue = clientName.getText().toString().trim(); int idValue = Integer.parseInt(clientId.getText().toString().trim()); String walletValue = clientWallet.getText().toString().trim(); double balanceValue = Double.parseDouble(clientBalance.getText().toString().trim()); // 添加新客户端到列表 clientListItems.add(new Client(nameValue, idValue, new Wallet(walletValue, balanceValue), R.drawable.ic_launcher_foreground)); // 别忘了更新适配器,否则列表不会刷新显示新数据! clientAdapter.notifyDataSetChanged(); } }) .setNegativeButton("cancel", new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int id) { dialog.dismiss(); } }) .show(); }
这里额外提醒一句:添加完新数据后一定要调用clientAdapter.notifyDataSetChanged(),不然ListView不会自动刷新显示新添加的客户端。
方案二:在Dialog绑定布局后再查找控件
如果你更习惯从Dialog对象中获取控件,可以在给Builder设置好布局、创建并显示Dialog之后,或者在点击按钮时转换DialogInterface来查找:
void setAddingDialog(){ AlertDialog.Builder builder = new AlertDialog.Builder(this); LayoutInflater inflater = getLayoutInflater(); builder.setView(inflater.inflate(R.layout.dialog_add_new_client, null)) .setPositiveButton("add", new DialogInterface.OnClickListener(){ @Override public void onClick(DialogInterface dialogInterface, int i) { // 将DialogInterface转换为AlertDialog,此时布局已经绑定 AlertDialog dialog = (AlertDialog) dialogInterface; // 从Dialog中获取控件 EditText clientName = dialog.findViewById(R.id.newClientName); EditText clientId = dialog.findViewById(R.id.newClientId); EditText clientWallet = dialog.findViewById(R.id.newClientWallet); EditText clientBalance = dialog.findViewById(R.id.newClientBalance); // 后续处理逻辑和方案一一致 String nameValue = clientName.getText().toString().trim(); int idValue = Integer.parseInt(clientId.getText().toString().trim()); String walletValue = clientWallet.getText().toString().trim(); double balanceValue = Double.parseDouble(clientBalance.getText().toString().trim()); clientListItems.add(new Client(nameValue, idValue, new Wallet(walletValue, balanceValue), R.drawable.ic_launcher_foreground)); clientAdapter.notifyDataSetChanged(); } }) .setNegativeButton("cancel", new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int id) { dialog.dismiss(); } }); // 创建并显示Dialog AlertDialog alertDialog = builder.create(); alertDialog.show(); }
额外小建议
- 处理数字转换时(比如
Integer.parseInt、Double.parseDouble),最好加个异常捕获,防止用户输入非数字内容导致崩溃; - 可以在点击"add"按钮前先检查输入框是否为空,给用户相应提示,提升体验。
内容的提问来源于stack exchange,提问作者Wlad Guz
相关产品推荐
相关产品推荐

