BottomSheetDialogFragment - listen to dismissed by user event
Although all similar questions on SO suggest using onDismiss
I think following is the correct solution:
@Overridepublic void onCancel(DialogInterface dialog){ super.onCancel(dialog); Toast.makeText(MainApp.get(), "CANCEL", Toast.LENGTH_SHORT).show();}
This fires if:
* the user presses back* the user presses outside of the dialog
This fires NOT:
* on screen rotation and activity recreation
Solution
Combine onCancel and BottomSheetBehavior.BottomSheetCallback.onStateChanged like following:
public class Dailog extends BottomSheetDialogFragment{ @Override public void onCancel(DialogInterface dialog) { super.onCancel(dialog); handleUserExit(); } @Override public Dialog onCreateDialog(Bundle savedInstanceState) { Dialog d = super.onCreateDialog(savedInstanceState); d.setOnShowListener(new DialogInterface.OnShowListener() { @Override public void onShow(DialogInterface dialog) { BottomSheetDialog d = (BottomSheetDialog) dialog; FrameLayout bottomSheet = (FrameLayout) d.findViewById(android.support.design.R.id.design_bottom_sheet); BottomSheetBehavior behaviour = BottomSheetBehavior.from(bottomSheet); behaviour.setBottomSheetCallback(new BottomSheetBehavior.BottomSheetCallback() { @Override public void onStateChanged(@NonNull View bottomSheet, int newState) { if (newState == BottomSheetBehavior.STATE_HIDDEN) { handleUserExit(); dismiss(); } } @Override public void onSlide(@NonNull View bottomSheet, float slideOffset) { } }); } }); return d; } private void handleUserExit() { Toast.makeText(MainApp.get(), "TODO - SAVE data or similar", Toast.LENGTH_SHORT).show(); }}
If you extended from BottomSheetDialogFragment() just override in your class
override fun onDismiss(dialog: DialogInterface) { super.onDismiss(dialog) //Code here }
This will trigger when onBackPress and when you dismiss the dialog by clicking outside of it.
Make sure to NOT set your dialog as cancelable because this will not fire
i achieved this using this simple trick
val bottomSheetDialog = FeedbackFormsFragment.createInstance()bottomSheetDialog.show((activity as FragmentActivity).supportFragmentManager, BOTTOM_SHEET)// add some delay to allow the bottom sheet to be visible first so that the dialog is not null Handler().postDelayed({ bottomSheetDialog.dialog?.setOnDismissListener { // add code here } }, 1000)