使用ButterKnife处理自定义AlertDialog时出现异常
解决AlertDialog自定义布局控件空指针异常问题
你遇到的空指针问题根源很明确——你试图通过Activity的@BindView注解绑定自定义Dialog布局里的控件,但这些控件根本不属于Activity的布局文件,所以ButterKnife无法完成绑定,导致txtNotes、txtSuggestprice等变量都是null,调用getText()时自然抛出异常。另外还有一个小问题:你在Dialog还没显示、用户还没输入内容的时候就获取EditText的文本,这不仅毫无意义,还会提前触发空指针。
下面是修复后的完整方案:
步骤1:移除不属于Activity的@BindView注解
首先把那些属于Dialog布局的控件注解删掉,因为它们不在activity_show_the_post.xml里,ButterKnife无法绑定:
// 删掉这些行 // @Nullable @BindView(R.id.priceSuggested) EditText txtSuggestprice; // @Nullable @BindView(R.id.txtnotes) EditText txtNotes; // @Nullable @BindView(R.id.btnClose) Button btnclose; // @Nullable @BindView(R.id.btnCommentDone) Button btndone;
步骤2:修改ShowCommentDialog方法,通过Dialog的View获取控件
在Dialog初始化时,通过你inflated的dialogView来查找自定义布局里的控件,并且把获取文本的逻辑放到按钮点击事件中(等用户输入后再获取):
public void ShowCommentDialog() { final AlertDialog.Builder alert = new AlertDialog.Builder(this); // 直接用Activity本身作为Context View dialogView = getLayoutInflater().inflate(R.layout.create_comment, null); alert.setCancelable(false); alert.setView(dialogView); final AlertDialog dialog = alert.create(); // 从Dialog的布局View中获取控件 EditText txtSuggestprice = dialogView.findViewById(R.id.priceSuggested); EditText txtNotes = dialogView.findViewById(R.id.txtnotes); Button btnclose = dialogView.findViewById(R.id.btnClose); Button btndone = dialogView.findViewById(R.id.btnCommentDone); alert.setPositiveButton("Done", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { // 此时用户已经输入内容,再获取文本 String notes = txtNotes.getText().toString(); String price = txtSuggestprice.getText().toString(); Toasty.success(ShowThePost.this, "Done: " + notes + " " + price, Toast.LENGTH_LONG).show(); } }).setNegativeButton("Close", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { dialog.dismiss(); } }); btndone.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { String notes = txtNotes.getText().toString(); String price = txtSuggestprice.getText().toString(); Toasty.success(ShowThePost.this, "Done: " + notes + " " + price, Toast.LENGTH_LONG).show(); dialog.dismiss(); } }); btnclose.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Toast.makeText(ShowThePost.this, "Closed", Toast.LENGTH_SHORT).show(); dialog.dismiss(); } }); dialog.getWindow().setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT)); dialog.show(); }
关键注意点
- 控件归属问题:Dialog的布局控件必须通过Dialog自己的inflated View来查找,不能依赖Activity的
findViewById或ButterKnife的Activity绑定,因为两者属于不同的布局层级。 - 文本获取时机:一定要在用户完成输入、触发提交动作(比如点击Done按钮)时再获取EditText的文本,不要在Dialog初始化阶段就获取,此时控件可能还未完成初始化,而且用户还没输入内容。
内容的提问来源于stack exchange,提问作者user7050829
相关产品推荐
相关产品推荐

