在Android开发中,AlertDialog的使用十分频繁的,有时候会碰到点击确定或取消后AlertDialog仍不消失的需求,但在Android的SDK中并没有给出接口来实现这一功能,故我们通过研究Android AlertDialog的源代码来通过反射进行修改来完成这一需求。
查看/core/java/android/app/Dialog.java的源代码:
void dismissDialog() {
if (mDecor == null || !mShowing) {
return;
}
if (mWindow.isDestroyed()) {
Log.e(TAG, "Tried to dismissDialog() but the Dialog's window was already destroyed!");
return;
}
try {
mWindowManager.removeViewImmediate(mDecor);
} finally {
if (mActionMode != null) {
mActionMode.finish();
}
mDecor = null;
mWindow.closeAllPanels();
onStop();
mShowing = false;
sendDismissMessage();
}
}
其中有dismissDialog()这一方法,可以看到Android设置了mShowing这一变量来判断dialog是否消失,当mShowing为true时则执行sendDismissMessage()方法使dialog消失,当mShowing为false则return,故只要我们将mShowing这一变量设置为false则不会执行sendDismissMessage()使dialog消失。
我们通过反射这一手段来修改mShowing的值:
try {
Field field = dialog.getClass().getSuperclass().getDeclaredField("mShowing");
field.setAccessible(true);
field.set(dialog, false);
} catch (Exception e) {
e.printStackTrace();
}
以下是一个小Demo:
new AlertDialog.Builder(this).setMessage("测试").setPositiveButton("确定",
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
try {
Field field = dialog.getClass().getSuperclass()
.getDeclaredField("mShowing");
field.setAccessible(true);
field.set(dialog, false);
} catch (Exception e) {
e.printStackTrace();
}
}
}).setNegativeButton("取消", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
try {
Field field = dialog.getClass().getSuperclass()
.getDeclaredField("mShowing");
field.setAccessible(true);
field.set(dialog, true);
dialog.dismiss();
} catch (Exception e) {
e.printStackTrace();
}
}
}).show();