Detect back button but don't dismiss dialogfra

2019-01-08 14:40发布

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).

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.

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.

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.

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?

8条回答
来,给爷笑一个
2楼-- · 2019-01-08 14:55

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!

查看更多
别忘想泡老子
3楼-- · 2019-01-08 14:59

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;
}
查看更多
Viruses.
4楼-- · 2019-01-08 15:07
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
    Dialog dialog = new Dialog(getActivity(), getTheme()) {
        @Override
        public void onBackPressed() {
            //your code
        }
    };

    return dialog;
}
查看更多
ゆ 、 Hurt°
5楼-- · 2019-01-08 15:08

Use Fragment onCancel override method. It's called when you press back. here is a sample:

@Override
public void onCancel(DialogInterface dialog) {
    super.onCancel(dialog);

    // Add you codition
}
查看更多
趁早两清
6楼-- · 2019-01-08 15:11

The best way and cleanest way is to override onBackPressed() in the dialog you created in onCreateDialog().

@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
    return new Dialog(getActivity(), getTheme()){
        @Override
        public void onBackPressed() {
            //do your stuff
        }
    };
}
查看更多
Deceive 欺骗
7楼-- · 2019-01-08 15:13

Use onDismiss() callback of DialogFragment with a closeActivity flag

private var closeActivity: Boolean = true    

override fun onDismiss(dialog: DialogInterface?) {
        super.onDismiss(dialog)

        if (closeActivity) {
            activity!!.finish()
        }
    }
查看更多
登录 后发表回答