Android 检测后退按钮但不关闭对话框片段
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/21307858/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Detect back button but don't dismiss dialogfragment
提问by user3227652
I have a dialogfragment for a floating dialog which includes a special keyboard that pops up when a user presses inside an EditText field (the normal IME is stopped from being displayed).
我有一个浮动对话框的对话框片段,其中包括一个特殊的键盘,当用户在 EditText 字段内按下时会弹出该键盘(停止显示正常的 IME)。
I would like the keyboard to be dismissed (visibility = GONE) when the user presses the back button (just as with a normal IME service) but the dialog to remain visible. However, there does not appear to be a way to do this as far as I can see from my fairly extensive reading on SO and elsewhere.
我希望在用户按下后退按钮(就像使用普通 IME 服务一样)时关闭键盘(可见性 = GONE),但对话框保持可见。但是,从我对 SO 和其他地方的相当广泛的阅读中可以看出,似乎没有办法做到这一点。
If I set the dialog to be non-cancelable then I don't get notified by onCancel() or onDismiss() because the dialog isn't cancelable.
如果我将对话框设置为不可取消,则 onCancel() 或 onDismiss() 不会通知我,因为该对话框不可取消。
If I set the dialog to be cancelable then I get notified, but the dialog is dismissed.
如果我将对话框设置为可取消,则会收到通知,但对话框会被关闭。
I can't attach an onKeyListener to the dialog in the fragment because it is replaced by the system so that the fragment can handle the dialog's life cycle.
我无法将 onKeyListener 附加到片段中的对话框,因为它已被系统替换,以便片段可以处理对话框的生命周期。
Is there any way to do this? Or has access to the detection of key events been entirely fenced off for the purposes of the Fragment system?
有没有办法做到这一点?或者,为了 Fragment 系统的目的,对关键事件的检测是否被完全屏蔽了?
回答by Ian Wong
The best way and cleanest way is to override onBackPressed() in the dialog you created in onCreateDialog().
最好的方法和最简洁的方法是在您在 onCreateDialog() 中创建的对话框中覆盖 onBackPressed()。
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
return new Dialog(getActivity(), getTheme()){
@Override
public void onBackPressed() {
//do your stuff
}
};
}
回答by Juan Pedro Martinez
I had the same problem than you and I've fixed it attaching the onKeyListener to the dialogfragment.
我遇到了和你一样的问题,我已经修复了它,将 onKeyListener 附加到对话框片段。
In the method onResume()
of the class that extend of DialogFragment put these piece of code:
在onResume()
DialogFragment 的扩展类的方法中放了这段代码:
getDialog().setOnKeyListener(new OnKeyListener()
{
@Override
public boolean onKey(android.content.DialogInterface dialog, int keyCode,android.view.KeyEvent event) {
if ((keyCode == android.view.KeyEvent.KEYCODE_BACK))
{
//Hide your keyboard here!!!
return true; // pretend we've processed it
}
else
return false; // pass on to be processed as normal
}
});
Here one of the problems that you can find is this code is going to be executed twice: one when the user press tha back button and another one when he leave to press it. In that case, you have to filter by event:
您可以在这里发现的问题之一是这段代码将被执行两次:一次是在用户按下后退按钮时,另一次是在他离开时按下它。在这种情况下,您必须按事件过滤:
@Override
public void onResume() {
super.onResume();
getDialog().setOnKeyListener(new OnKeyListener()
{
@Override
public boolean onKey(android.content.DialogInterface dialog, int keyCode,
android.view.KeyEvent event) {
if ((keyCode == android.view.KeyEvent.KEYCODE_BACK))
{
//This is the filter
if (event.getAction()!=KeyEvent.ACTION_DOWN)
return true;
else
{
//Hide your keyboard here!!!!!!
return true; // pretend we've processed it
}
}
else
return false; // pass on to be processed as normal
}
});
}
回答by Brandon
As an addendum to Juan Pedro Martinez's answer I thought it would be helpful to clarify a specific question (one that I had) when looking at this thread.
作为胡安·佩德罗·马丁内斯 (Juan Pedro Martinez) 回答的附录,我认为在查看此线程时澄清一个特定问题(我遇到的问题)会有所帮助。
If you wish to create a new DialogFragment and have it so the user can only cancel it using the back-button, which eliminates random screen touches from canceling the fragment prematurely, then this is the code that you would use.
如果您希望创建一个新的 DialogFragment 并拥有它,以便用户只能使用后退按钮取消它,从而消除随机屏幕触摸过早取消片段,那么这就是您将使用的代码。
In what ever code that you call the DialogFragment you need to set the cancelable setting to false so that NOTHING dismisses the fragment, no stray screen touches, etc.
在您调用 DialogFragment 的任何代码中,您需要将可取消设置设置为 false 以便没有任何内容消除片段,没有杂散的屏幕触摸等。
DialogFragment mDialog= new MyDialogFragment();
mDialog.setCancelable(false);
mDialog.show(getFragmentManager(), "dialog");
Then, within your DialogFragment, in this case MyDaialogFragment.java, you add the onResume override code to have the dialog listen for the Back Button. When it's pressed it will execute the dismiss() to close the fragment.
然后,在您的 DialogFragment 中,在本例中为 MyDaialogFragment.java,您添加 onResume 覆盖代码以使对话框侦听后退按钮。当它被按下时,它会执行dismiss() 来关闭片段。
@Override
public void onResume()
{
super.onResume();
getDialog().setOnKeyListener(new OnKeyListener()
{
@Override
public boolean onKey(android.content.DialogInterface dialog,
int keyCode,android.view.KeyEvent event)
{
if ((keyCode == android.view.KeyEvent.KEYCODE_BACK))
{
// To dismiss the fragment when the back-button is pressed.
dismiss();
return true;
}
// Otherwise, do nothing else
else return false;
}
});
Now your dialog will be called with the "setCancelable" to false, meaning nothing (no outside clicks) can cancel it and shut it down, and allowing (from within the dialog itself) only the back button to close it.
现在,您的对话框将使用“setCancelable”为 false 来调用,这意味着没有任何东西(没有外部点击)可以取消它并关闭它,并且只允许(从对话框本身内)使用后退按钮来关闭它。
Ganbatte!
甘巴特!
回答by Andrew James
How has no one suggested this?
怎么没人推荐这个?
public Dialog onCreateDialog(Bundle savedInstanceState) {
Dialog dialog = super.onCreateDialog(savedInstanceState);
// Add back button listener
dialog.setOnKeyListener(new Dialog.OnKeyListener() {
@Override
public boolean onKey(DialogInterface dialogInterface, int keyCode, KeyEvent keyEvent) {
// getAction to make sure this doesn't double fire
if (keyCode == KeyEvent.KEYCODE_BACK && keyEvent.getAction() == KeyEvent.ACTION_UP) {
// Your code here
return true; // Capture onKey
}
return false; // Don't capture
}
});
return dialog;
}
回答by Manimaran A
Use Fragment onCancel override method. It's called when you press back. here is a sample:
使用 Fragment onCancel 覆盖方法。当您按下返回键时会调用它。这是一个示例:
@Override
public void onCancel(DialogInterface dialog) {
super.onCancel(dialog);
// Add you codition
}
回答by android developer
When creating the dialog, override both onBackPressed and onTouchEvent :
创建对话框时,覆盖 onBackPressed 和 onTouchEvent :
final Dialog dialog = new Dialog(activity) {
@Override
public boolean onTouchEvent(final MotionEvent event) {
//note: all touch events that occur here are outside the dialog, yet their type is just touching-down
boolean shouldAvoidDismissing = ... ;
if (shouldAvoidDismissing)
return true;
return super.onTouchEvent(event);
}
@Override
public void onBackPressed() {
boolean shouldAvoidDismissing = ... ;
if (!shouldSwitchToInviteMode)
dismiss();
else
...
}
};
回答by Vasudev
Use onDismiss() callback of DialogFragment with a closeActivityflag
使用带有closeActivity标志的 DialogFragment 的 onDismiss() 回调
private var closeActivity: Boolean = true
override fun onDismiss(dialog: DialogInterface?) {
super.onDismiss(dialog)
if (closeActivity) {
activity!!.finish()
}
}