对于开发Android的朋友来说Activity的生命周期肯定不陌生,但是对于Dialog的生命周期就会有点困惑了,可能会问咋个Dialog还有生命周期呢?没错,Dialog不仅有生命周期而且会与Activity有密切的关联。相信用过Dialog的朋友肯定记得如何让Dialog消失的方法:就是调用dialog.cancle 或 dialog.dismiss()方法。OK,那么,下面我们先看一下Dialog 的六个生命周期。
前言
一、Dialog生命周期
二、Activity上有Dialog的时候的生命周期
三、封装对话框管理类
是不是看着很眼熟,当在对话框创建onCreate()后(仅执行一次创建),show()方法用于展示对话框,随后调用onStart(),当点击back键或点击外部会执行cancel(),如果调用dialog.dismiss()方法会执行onDismiss,对话框消失最后会执行Stop()。
Android 深刻理解Activity生命周期的作用及意义
有些朋友可能会认为Activity被覆盖会处于onPause的生命周期,完全不可见即将销毁则处于onStop状态, 但是弹出Dialog覆盖时会不会这样呢?很简单的做个试验: 点击按钮弹出一个Dialog, 这时后面的Activity处于不完全可见的状态, 打印出Activity生命周期的变化。
public class MainActivity extends AppCompatActivity {
private Button button;
private String TAG = "MainActivity";
public void init(){
button = findViewById(R.id.button);
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
AlertDialog dialog = new AlertDialog.Builder(MainActivity.this)
.setIcon(R.mipmap.ic_launcher_round)
.setCancelable(false)
.setTitle("dialog")
.show();
}
});
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
init();
}
protected void onStart(){
Log.d(TAG,"onStart方法正在执行");
super.onStart();
}
protected void onResume(){
Log.d(TAG,"onResume方法正在执行");
super.onResume();
}
protected void onPause(){
Log.d(TAG,"onPause方法正在执行");
super.onPause();
}
protected void onStop(){
Log.d(TAG,"onStop方法正在执行");
super.onStop();
}
protected void onDestroy(){
Log.d(TAG,"onDestroy方法正在执行");
super.onDestroy();
}
}
程序打开后,点击弹框,生命周期显示是:onCreate() -> onStart() -> onResume 。这表明弹出的东西对后面Activity的生命周期并没有影响。
官方文档我们可以看到: onPause():Called when the system is about to start resuming another activity. (启动另外一个Activity的时候才会进入onPause状态)
Dialog实现的原理是windowmanager.addView();其实添加的是一个view。所以,我们弹出的Dialog对话框实际上是Activity的一个组件,Activity并不是不可见而是被一个布满屏幕的组件覆盖到最顶层,我们无法对其他内容进行操作,因此,Dialog不会影响Activity的生命周期的变化。
如果在弹出对话框的Activity点击home键返回桌面,Activity生命周期会不会变化呢?当然会,会执行onPause() -> onStop() 。
再次启动: onRestart() -> onStart() -> onResume()。(有没有Dialog生命周期都不会发生变化)
通过对support v4/v7/v13的区别我们了解到v7最低兼容Android2.1版本的系统,所以我们使用Dialog可以这样导入:
import android.support.v7.app.AlertDialog;
//对话框
private static AlertDialog alertDialog;
/**
* 显示单独按钮的Dialog
*/
public static void showSimpleDialog(Activity context, String title, String message , DialogInterface.OnClickListener clickListener) {
AlertDialog.Builder builder =new AlertDialog.Builder(context);
builder.setCancelable(true);
builder.setTitle(title);
builder.setMessage(message);
//监听事件
if (clickListener != null){
builder.setPositiveButton("确认",clickListener);
}else{
builder.setNegativeButton("知道了",null);
}
alertDialog=builder.create();
alertDialog.setCanceledOnTouchOutside(false);
if(!((Activity) context).isFinishing()){
alertDialog.show();
}
}
/**
* 显示双按钮Dialog
*/
public static void showDoubleDialog(Activity context, String title, String message , DialogInterface.OnClickListener clickListener) {
AlertDialog.Builder builder =new AlertDialog.Builder(context);
builder.setCancelable(true);
builder.setTitle(title);
builder.setMessage(message);
//监听事件
if (clickListener != null){
builder.setPositiveButton("确认",clickListener);
}else{
builder.setPositiveButton("确认",null);
}
builder.setNegativeButton("取消",null);
alertDialog=builder.create();
alertDialog.setCanceledOnTouchOutside(false);
if(!context.isFinishing()){
alertDialog.show();
}
}
进度条对话框,需要自定义布局:
//进度条
private static Dialog progressDialog;
/**
* 显示进度条
* @param context
* @param msg
*/
public static void showProgress(Activity context,String msg){
if (progressDialog == null){
progressDialog = new Dialog(context , R.style.loadingdialog);
progressDialog.setContentView(R.layout.loading_dialog);
progressDialog.setCanceledOnTouchOutside(false);
} else if (progressDialog.isShowing()){
progressDialog.dismiss();
}
if(!context.isFinishing())
{
progressDialog.show();
}
}
/**
* 关闭进度条
*/
public static void dismissProgress(){
if (progressDialog != null ){
if (progressDialog.isShowing()){
progressDialog.dismiss();
}
}
}
其中布局:R.layout.loading_dialog:
其中ProgressBar的Style.Theme: R.style.loadingdialog
其中ProgressBar属性android:indeterminateDrawable="@drawable/progressbar_bg"