Android 通过继承Dialog自定义Dialog使用注意事项

一、视图加载方式的区别

给Dialog添加布局文件有两种方式:
1.和Activity一样, 在onCreate中通过setContentView方法添加;
2. 通过LayoutInflate添加,可在构造方法中添加。

问题

在项目某Activity中看到这样的代码:

private CustomDialog mDialog;

public void showDelDialog() {
	if (mDialog == null){
		mDialog = new CustomDialog(this);
		mDialog.show();
	}
	mDialog.setNickName("xxx");
	...省略
	if(!mDialog.isShowing) {
		mDialog.show();
	}
}

其中,setNickName就是给控件设置文本

public void setNickName(String text) {
	nickNameTv.setText(text);
}

看这个逻辑,为啥先调用show,然后调用setNickName;而不是先调用setNickName,再调用show。
这里的CustomDialog是通过onCreate的setContentView来加载布局文件的。

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.dialog_custom);
        okTv = findViewById(R.id.dialog_ok);
        noTv = findViewById(R.id.dialog_cancel);
        nickNameTv = findViewById(R.id.nick_name_tv);
        personImgIv = findViewById(R.id.person_img_iv);
        okTv.setOnClickListener(this);
        noTv.setOnClickListener(this);
        Log.d(TAG, "onCreate() called with: savedInstanceState = [" + savedInstanceState + "]");
    }

强迫症的我打算去掉初始化时的show方法,如下

if (mDialog == null){
		mDialog = new CustomDialog(this);
	}

结果,运行时崩了,报了个空指针,而在初始化时加上show方法就不会。
为此,看了下show方法,发现只有在show方法以后才调用onCreate,如下:

  public void show() {
        if (mShowing) {
            if (mDecor != null) {
                if (mWindow.hasFeature(Window.FEATURE_ACTION_BAR)) {
                    mWindow.invalidatePanelMenu(Window.FEATURE_ACTION_BAR);
                }
                mDecor.setVisibility(View.VISIBLE);
            }
            return;
        }

        mCanceled = false;

        if (!mCreated) {
            dispatchOnCreate(null); // 此处调用onCreate方法
        } else {
            // Fill the DecorView in on any configuration changes that
            // may have occured while it was removed from the WindowManager.
            final Configuration config = mContext.getResources().getConfiguration();
            mWindow.getDecorView().dispatchConfigurationChanged(config);
        }

        onStart();
	     ...}

因此,更新控件需要在onCreate方法调用以后,即调用show方法以后才能做更新视图的操作。

于是,试了另外一种加载视图的方式,在构造方法中加载视图:

 public CustomDialog(Context context) {
        this(context, R.style.CustomDialog); // 设置自定义样式
        setCanceledOnTouchOutside(false);
        setCancelable(false);
        Log.d(TAG, "CustomDialog() called with: context = [" + context + "]");
        View inflate = LayoutInflater.from(context).inflate(R.layout.dialog_custom, null);
        okTv = inflate.findViewById(R.id.dialog_ok);
        noTv = inflate.findViewById(R.id.dialog_cancel);
        nickNameTv = inflate.findViewById(R.id.nick_name_tv);
        personImgIv = inflate.findViewById(R.id.person_img_iv);
        okTv.setOnClickListener(this);
        noTv.setOnClickListener(this);
        setContentView(inflate);
        this.context = context;
    }

采用这种方法,在初始化时并不需要调用show方法,就可以更新控件了,然后在需要的地方再调用show方法。

结论

1.第一种,如果在没有调用show方法,即视图没有加载的时候去更新控件,就会报空指针。

而采用第二种方法,由于一开始便绑定了视图,因此在没有调用show方法的时候去更新控件,是可以的。

二.生命周期

主要生命周期:onCreate–>onStart–>onStop

当调用show以后会分别执行onCreate–>onStart,onCreate只会调用一次,onStart会调用多次。
当调用dismiss以后会调用onStop。

2.生命周期及其它方法
在这里插入图片描述
调用show以后:onCreate–>onStart–>onAttachedToWindow()–>onWindowFocusChanged()
调用dismiss以后:onDetachedFromWindow()–>onStop()

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值