一、视图加载方式的区别
给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()