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
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
可以按照以下步骤自定义一个弹窗: 1. 在Activity中重写onCreateDialog()方法,返回一个Dialog对象。 2. 在Dialog对象的构造函数中设置弹窗的样式、布局和监听事件。 3. 在Activity中调用showDialog()方法显示弹窗。 以下是示例代码: ```java public class MainActivity extends AppCompatActivity { private static final int DIALOG_CUSTOM = 1; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); // 显示自定义弹窗 showDialog(DIALOG_CUSTOM); } @Override protected Dialog onCreateDialog(int id) { switch (id) { case DIALOG_CUSTOM: // 创建自定义弹窗 Dialog dialog = new Dialog(this); dialog.setContentView(R.layout.dialog_custom); dialog.setTitle("自定义弹窗"); // 设置按钮的监听事件 Button btnOk = dialog.findViewById(R.id.btn_ok); btnOk.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { // 处理确定按钮的点击事件 Toast.makeText(MainActivity.this, "点击了确定按钮", Toast.LENGTH_SHORT).show(); dismissDialog(DIALOG_CUSTOM); } }); Button btnCancel = dialog.findViewById(R.id.btn_cancel); btnCancel.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { // 处理取消按钮的点击事件 Toast.makeText(MainActivity.this, "点击了取消按钮", Toast.LENGTH_SHORT).show(); dismissDialog(DIALOG_CUSTOM); } }); return dialog; } return super.onCreateDialog(id); } } ``` 在上面的代码中,我们创建了一个自定义弹窗,并设置了确定和取消按钮的点击事件。在Activity的onCreate()方法中,调用showDialog()方法显示弹窗。当用户点击按钮时,弹窗会被关闭。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值