dialog使用时需要注意的问题:
- 在Activity关闭前一定要先把dialog给dismiss掉,否则会报错,activity状态判断方法如下:
boolean finishing = activity.isFinishing(); //
boolean b = activity.hasWindowFocus(); //windown显示在当前时候才获取焦点,才为true
boolean destroyed = activity.isDestroyed(); //需要android版本在17以上
- 其所使用的context必须要用Activity的;
- 作为工具类中的通用方法时,需要注意 "顶层、单一"显示原则;
- 在调用dialog.show();前,一定要先判断其所依赖的Activity是否还存在;
- 在给Dialog全屏设置时,需要先进行:dialog.getWindow().getDecorView().setPadding(0, 0, 0, 0); 因为对话框的样式文件内部有pading属性,否则不管我们怎样设置lp.width,lp.x,lp.y对话框水平方向是占不满的,左右始终是有间距的。
- 报View not attached to window manager 错误:
这个错误的意思是说我们所操作的View没有被纳入window manager的管理。因为所有的窗口创建和管理都是依附于window manager的,因此Dialog的创建也不例外。
错误分析:在Dialog显示期间,该Activity因为某种原因被杀掉且又重新启动了,那么当任务结束时,Dismiss Dialog的时候WindowManager检查,就会发现该Dialog所属的Activity已经不存在了(重新启动了一次,是一个新的Activity),所以会报IllegalArgumentException: View not attached to window manager.(注意:当某个activity变得“容易”被系统销毁时,该activity的onSaveInstanceState就会被执行,除非该activity是被用户主动销毁的,例如当用户按BACK键的时候。)
- 如何解决这个问题呢?
1.使用Activity自带的Dialog控制方法:
在Activity中需要使用对话框,可以使用Activity自带的回调,比如onCreateDialog(),showDialog(),dimissDialog(),removeDialog()等等。毕竟这些都是Activity自带的方法,所以用起来更方便,也不用显示创建和操控Dialog对象,一切都由框架操控,相对来说比较安全。
2.限制Dialog的生命周期:
让创建的Dialog对象的存活周期跟Activity的生命周期一致,也就是说Dialog的生命周期被限定在Activity的onCreate()和onDestroy()方法之间。
实例:
public static void showDialog(final Activity activity) {
if (alert != null && alert.isShowing()) { //设置只在最顶层显示一个dialog
alert.dismiss();
alert = null;
}
builder = new AlertDialog.Builder(activity);
alert = builder.setTitle("下线通知")
.setMessage("您的账号已于异地登录")
.setNeutralButton("退出", new DialogInterface.OnClickListener() {
@Override public void onClick(DialogInterface dialog, int which) {
SPTools.put(activity, Constant.TOKEN, "");
activity.startActivity(new Intent(activity, LoginActivity.class));
alert.dismiss();
}
})
.setPositiveButton("重新登录", new DialogInterface.OnClickListener() {
@Override public void onClick(DialogInterface dialog, int which) {
SPTools.put(activity, Constant.TOKEN, "");
activity.startActivity(new Intent(activity, LoginActivity.class));
alert.dismiss();
}
})
.create(); //创建AlertDialog对象
alert.setCanceledOnTouchOutside(false);
alert.setCancelable(false);
if (activity.isFinishing()) {
alert.show();
}
}
附加:
Dialog应用举例:
Dialog picDialog = new Dialog(activity, R.style.AlertDialogStyle); //自带属性设置
Window dialogWindow = picDialog.getWindow();
picDialog.setContentView(dialogContentView);
picDialog.setCancelable(true);
dialogWindow.setWindowAnimations(R.style.DialogBottom); //dialog添加动画
dialogWindow.setGravity(Gravity.BOTTOM);
picDialog.show();
<!-- 照相机相册显示AlertDialog的样式 -->
<style name="AlertDialogStyle" parent="@android:style/Theme.Dialog">
<item name="android:windowBackground">@android:color/transparent</item><!--背景透明-->
<item name="android:windowContentOverlay">@null</item>
<item name="android:windowIsFloating">true</item><!--是否浮现在activity之上-->
<item name="android:windowFrame">@null</item><!--边框-->
<item name="android:backgroundDimEnabled">true</item><!--模糊-->
<item name="android:windowNoTitle">true</item><!--无标题-->
<item name="android:windowIsTranslucent">false</item><!--半透明-->
</style>
<!-- Dialog的动画样式 -->
<style name="DialogBottom">
<item name="@android:windowEnterAnimation">@anim/dialog_enter</item>
<item name="@android:windowExitAnimation">@anim/dialog_exit</item>
</style>
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<translate
android:fromYDelta="50%p"
android:duration="200"
/>
</set>
.