自定义Dialog报空指针的一个坑(为什么需要先调用show()?)

首先是坑:

有一个自定义Dialog:

public class MyDialog extends Dialog {
    private TextView dialogTitle;

    public MyDialog(@NonNull Context context) { //构造方法
        super(context);
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.base_my_dialog);
        initView();//绑定控件方法
    }

    private void initView() {
        dialogTitle = findViewById(R.id.base_dialog_title);
    }

    //给外边调用,设置标题的方法(这里直接使用控件设置)
    public void setTitle(String title) {
        dialogTitle.setText(title);
    }
}
先以上边的自定义Dialog为例

如果你这个顺序使用是错的:会报空指针

MyDialog dialog = new MyDialog();
dialog.setTitle("标题");
dialog.show();

这才是对的:

MyDialog dialog = new MyDialog();
dialog.show();
dialog.setTitle("标题");

纳尼???
可能是我太菜其实原因很简单

★★原因: dialog在new 的时候 并不会执行 onCreate() 方法 因此里面的控件都未初始化 而调用dialog.show()的时候才会执行onCreate() 方法;

★★所以,你使用时必须先调用show(),这样onCreate()方法才会被调用,你的控件才会绑定视图,不然就会报空指针

★★ 还有一点:你对dialog大小的设置也需要在show()之后,show方法会 创建新的 DecorView,在DecorView创建时会清理掉你设置的宽高

好了,说完坑,再说下怎么解决:

解决:

可能有些朋友和我一样,就是觉得这么先show()再设置属性很难受!!那么就看看下边的。。。

换一种方式自定义Dialog:

public class MyDialog extends Dialog {
    private TextView dialogTitle;
    private TextView dialogContent;
    private String title;
    private String Content;

    public MyDialog(@NonNull Context context) { //构造方法
        super(context);
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.base_my_dialog);
        initView();//绑定控件方法
        addDialogContent();通过此方法给dialog中的view统一赋值
    }

    private void initView() {
        dialogTitle = findViewById(R.id.base_dialog_title);
        dialogContent = findViewById(R.id.base_dialog_content);
    }

    ★★设置标题的方法(这里把参数接收下来,不直接给控件赋值就避免了空指针)★★
    public MyDialog setTitle(String title) {
        this.title = title;
        return this;  返回值是Mydialog就可以实现链式调用
    }

    public MyDialog setContent(String content) {
        this.content = content;
        return this;
    }

    通过此方法给dialog统一添加内容
    private void addDialogContent() {
        if (!TextUtils.isEmpty(title)) {
            dialogTitle.setText(title);
        }
        if (!TextUtils.isEmpty(content)) {
            dialogContent.setText(content);
        }
    }
}

★★解释一下上面写法解决的问题:

1:解决空指针: 上边的写法不需要直接给View赋值了,你调用的setTitle方法只是把参数传到了Mydialog中,并没有直接赋值给TextView,这样就不会出现空指针问题了。

2:解决View的赋值: 参数的值接收到了,然后在onCreate方法中写一个方法给MyDialog的View统一赋值(此方法需要写在控件绑定方法的后边执行),这样就完成了View的赋值。

3:效果: 因为你的set方法避免了使用View直接赋值,所以就不会出现空指针,所以你就不需要先写show()方法再写属性了,并且你的View赋值方法写在了onCreate中的绑定view方法之后,所以这样就肯定不会出现空指针了!

使用:

这样就可以愉快的先设置属性,在调用show()方法了!舒服!

              final MyDialog dialog = new MyDialog(this);
                    dialog.setDialogTitle("提示")
                    .setDialogContent("注册成功")
                    .setDialogNoBtn("不了", new MyDialog.MyDialogNoBtnListener() {
                        @Override
                        public void onClick() {
                          dialog.dismiss();
                        }
                    })
                    .setDialogYesBtn("去登录", new MyDialog.MyDialogYesBtnListener() {
                        @Override
                        public void onClick() {
                            finish();
                        }
                    }).show();

问题挺简单,可能自己还是踩坑太少,写这篇文章记录下,有不对的地方还请帮忙指出!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值