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 bei
I had the same problem than you and I've fixed it attaching the onKeyListener to the dialogfragment.
In the method onResume()
of the class that extend of DialogFragment put these piece of code:
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
}
});
}
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.
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.
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 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.
@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.
Ganbatte!
AndroidX OnBackPressedDispatcher can also be option for someone