控制Android弹出框不消失
Android中的弹出框在被点击时, 无论点击哪个按钮都会关闭窗口。 但是有的情况下我们不需要立即关闭窗口。下面的情况是弹出框中要求用户输入文件名, 并在点击确定时检查文件名的合法性, 不合法则提示用户重新输入, 弹出框要保持在界面上。 点击取消时弹出框消失。 这里通过对控件的反射来实现:
/**our button handler**/
private ButtonHandler bHandler;
//pop up dialog with own button handler
private void popUpDialog(AlertDialog dialog) {
/*
* alert dialog's default handler will always close dialog whenever user
* clicks on which button. we have to replace default handler with our
* own handler for blocking close action.
* Reflection helps a lot.
*/
try {
Field field = dialog.getClass().getDeclaredField("mAlert");
field.setAccessible(true);
//retrieve mAlert value
Object obj = field.get(dialog);
field = obj.getClass().getDeclaredField("mHandler");
field.setAccessible(true);
//replace mHandler with our own handler
field.set(obj, bHandler);
} catch (SecurityException e) {
Debug.error(e.getMessage());
} catch (NoSuchFieldException e) {
Debug.error(e.getMessage());
} catch (IllegalArgumentException e) {
Debug.error(e.getMessage());
} catch (IllegalAccessException e) {
Debug.error(e.getMessage());
}
//we can show this dialog now.
dialog.show();
}
/*
* define our own button handler, do not deal with dismiss message.
*/
class ButtonHandler extends Handler {
private WeakReference<DialogInterface> mDialog;
public ButtonHandler(DialogInterface dialog) {
mDialog = new WeakReference<DialogInterface>(dialog);
}
public void handleMessage(Message msg) {
switch (msg.what) {
case DialogInterface.BUTTON_POSITIVE:
case DialogInterface.BUTTON_NEGATIVE:
case DialogInterface.BUTTON_NEUTRAL:
((DialogInterface.OnClickListener) msg.obj).onClick(mDialog
.get(), msg.what);
break ;
}
}
}
然后创建一个AlertDialog时如下去调用:
//create dialog
mDialog = new AlertDialog.Builder(mContext)
.setView(selectImageView)
.setNegativeButton(android.R.string.cancel, mOnDialogClickListener)
.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int arg1) {
//check input file name
if (isValidFileName(fileNameInput.getText().toString())) {
String fileName = fileNameInput.getText().toString().trim();
mediaList.get(0).setName(fileName);
saveMedia(mediaList);
dialog.dismiss();
} else {
Toast.makeText(mContext, R.string.invalid_file_name, 1500).show();
}
}
}).create();
mOnDialogClickListener用来处理关闭窗口事件:
/*
* cancel dialog listener
*/
OnClickListener mOnDialogClickListener = new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int buttonId) {
switch (buttonId) {
case DialogInterface.BUTTON_NEGATIVE:
dialog.dismiss();
break;
case DialogInterface.BUTTON_POSITIVE:
break;
}
}
};
/**our button handler**/
private ButtonHandler bHandler;
//pop up dialog with own button handler
private void popUpDialog(AlertDialog dialog) {
/*
* alert dialog's default handler will always close dialog whenever user
* clicks on which button. we have to replace default handler with our
* own handler for blocking close action.
* Reflection helps a lot.
*/
try {
Field field = dialog.getClass().getDeclaredField("mAlert");
field.setAccessible(true);
//retrieve mAlert value
Object obj = field.get(dialog);
field = obj.getClass().getDeclaredField("mHandler");
field.setAccessible(true);
//replace mHandler with our own handler
field.set(obj, bHandler);
} catch (SecurityException e) {
Debug.error(e.getMessage());
} catch (NoSuchFieldException e) {
Debug.error(e.getMessage());
} catch (IllegalArgumentException e) {
Debug.error(e.getMessage());
} catch (IllegalAccessException e) {
Debug.error(e.getMessage());
}
//we can show this dialog now.
dialog.show();
}
/*
* define our own button handler, do not deal with dismiss message.
*/
class ButtonHandler extends Handler {
private WeakReference<DialogInterface> mDialog;
public ButtonHandler(DialogInterface dialog) {
mDialog = new WeakReference<DialogInterface>(dialog);
}
public void handleMessage(Message msg) {
switch (msg.what) {
case DialogInterface.BUTTON_POSITIVE:
case DialogInterface.BUTTON_NEGATIVE:
case DialogInterface.BUTTON_NEUTRAL:
((DialogInterface.OnClickListener) msg.obj).onClick(mDialog
.get(), msg.what);
break ;
}
}
}
然后创建一个AlertDialog时如下去调用:
//create dialog
mDialog = new AlertDialog.Builder(mContext)
.setView(selectImageView)
.setNegativeButton(android.R.string.cancel, mOnDialogClickListener)
.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int arg1) {
//check input file name
if (isValidFileName(fileNameInput.getText().toString())) {
String fileName = fileNameInput.getText().toString().trim();
mediaList.get(0).setName(fileName);
saveMedia(mediaList);
dialog.dismiss();
} else {
Toast.makeText(mContext, R.string.invalid_file_name, 1500).show();
}
}
}).create();
mOnDialogClickListener用来处理关闭窗口事件:
/*
* cancel dialog listener
*/
OnClickListener mOnDialogClickListener = new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int buttonId) {
switch (buttonId) {
case DialogInterface.BUTTON_NEGATIVE:
dialog.dismiss();
break;
case DialogInterface.BUTTON_POSITIVE:
break;
}
}
};
这篇文章转自: http://seya.iteye.com/blog/969103