我有一个浮动对话框的对话框片段,其中包含一个特殊的键盘,当用户在EditText字段内按下时会弹出(正常的IME停止显示)。
当用户按下后退按钮(就像使用普通的IME服务一样)时,我希望键盘被解除(visibility = GONE),但对话框仍然可见。但是,就我在SO和其他地方的相当广泛的阅读中所看到的,似乎没有办法做到这一点。
如果我将对话框设置为不可取消,那么我不会被onCancel()或onDismiss()通知,因为该对话框不可取消。
如果我将对话框设置为可取消,则会收到通知,但对话框将被取消。
我无法将onKeyListener附加到片段中的对话框,因为它被系统替换,以便片段可以处理对话框的生命周期。
有没有办法做到这一点?或者,为了Fragment系统的目的,是否可以访问完全围起来的关键事件的检测?
答案 0 :(得分:131)
最好的方法和最干净的方法是在onCreateDialog()中创建的对话框中覆盖onBackPressed()。
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
return new Dialog(getActivity(), getTheme()){
@Override
public void onBackPressed() {
//do your stuff
}
};
}
答案 1 :(得分:62)
我遇到了与你相同的问题,并且我已经修复了将onKeyListener附加到对话片段的问题。
在DialogFragment扩展类的方法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))
{
//Hide your keyboard here!!!
return true; // pretend we've processed it
}
else
return false; // pass on to be processed as normal
}
});
这里可以找到的问题之一是这个代码将被执行两次:一个是用户按下后退按钮而另一个是当他离开按下它时。在这种情况下,您必须按事件过滤:
@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
}
});
}
答案 2 :(得分:17)
作为胡安·佩德罗·马丁内斯答案的附录,我认为在查看这个帖子时澄清一个具体问题(我有一个问题)会有所帮助。
如果你想创建一个新的DialogFragment,并且让用户只能使用后退按钮取消它,这会消除随机屏幕触摸过早取消片段,那么这就是你要使用的代码。
在您调用DialogFragment的代码中,您需要将可取消设置设置为false,以便NOTHING解散片段,不会出现杂散屏幕触摸等。
DialogFragment mDialog= new MyDialogFragment();
mDialog.setCancelable(false);
mDialog.show(getFragmentManager(), "dialog");
然后,在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;
}
});
现在,您的对话框将使用" setCancelable"为假,没有任何意义(没有外部点击)可以取消它并关闭它,并允许(从对话框本身)只有后退按钮关闭它。
Ganbatte!
答案 3 :(得分:6)
没人提出这个建议?
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;
}
答案 4 :(得分:3)
使用Fragment onCancel覆盖方法。按下时会调用它。 这是一个示例:
@Override
public void onCancel(DialogInterface dialog) {
super.onCancel(dialog);
// Add you codition
}
答案 5 :(得分:1)
if (strEndsWith(person.lastName, "ian")) {
fprintf(arm, "%s, %s\n", person.lastName, person.firstName);
}
答案 6 :(得分:0)
创建对话框时,覆盖onBackPressed和onTouchEvent:
Settings
答案 7 :(得分:0)
使用带有 closeActivity 标志
的DialogFragment的onDismiss()回调private var closeActivity: Boolean = true
override fun onDismiss(dialog: DialogInterface?) {
super.onDismiss(dialog)
if (closeActivity) {
activity!!.finish()
}
}
答案 8 :(得分:0)
防止取消DialogFragment:
dialog.setCanceledOnTouchOutside(false)
dialog.setCancelable(false)
dialog.setOnKeyListener { dialog, keyCode, event ->
keyCode == KeyEvent.KEYCODE_BACK && event.action == KeyEvent.ACTION_UP
}
答案 9 :(得分:-1)
AndroidX OnBackPressedDispatcher也可以作为某人的选择