Comment puis-je écouter le rejet FINAL d'une BottomSheetDialogFragment
? Je souhaite enregistrer les modifications apportées aux utilisateurs lors du renvoi définitif uniquement ...
J'ai essayé de suivre:
Méthode 1
Cela ne se déclenche que si la boîte de dialogue est fermée en la glissant vers le bas (pas au dos, ni en contact avec l'extérieur)
@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) dialog.findViewById(Android.support.design.R.id.design_bottom_sheet);
BottomSheetBehavior behaviour = BottomSheetBehavior.from(bottomSheet);
behaviour.setState(BottomSheetBehavior.STATE_EXPANDED);
behaviour.setBottomSheetCallback(new BottomSheetBehavior.BottomSheetCallback() {
@Override
public void onStateChanged(@NonNull View bottomSheet, int newState) {
if (newState == BottomSheetBehavior.STATE_HIDDEN)
{
// Bottom Sheet was dismissed by user! But this is only fired, if dialog is swiped down! Not if touch outside dismissed the dialog or the back button
Toast.makeText(MainApp.get(), "HIDDEN", Toast.LENGTH_SHORT).show();
dismiss();
}
}
@Override
public void onSlide(@NonNull View bottomSheet, float slideOffset) {
}
});
}
});
return d;
}
Méthode 2
Cela ne me permet pas de faire la distinction entre un renvoi définitif et un renvoi résultant d'une rotation de l'écran ou d'une activité de loisir ...
@Override
public void onDismiss(DialogInterface dialog)
{
super.onDismiss(dialog);
// this works fine but fires one time too often for my use case, it fires on screen rotation as well, although this is a temporarily dismiss only
Toast.makeText(MainApp.get(), "DISMISSED", Toast.LENGTH_SHORT).show();
}
Question
Comment puis-je écouter un événement qui indique que l'utilisateur a terminé la boîte de dialogue?
Bien que toutes les questions similaires sur SO suggèrent d'utiliser onDismiss
, je pense que la solution suivante est la bonne:
@Override
public void onCancel(DialogInterface dialog)
{
super.onCancel(dialog);
Toast.makeText(MainApp.get(), "CANCEL", Toast.LENGTH_SHORT).show();
}
Cela se déclenche si:
* the user presses back
* the user presses outside of the dialog
Cela ne déclenche PAS:
* on screen rotation and activity recreation
Solution
Combinez onCancel et BottomSheetBehavior.BottomSheetCallback.onStateChanged comme suit:
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();
}
}
j'ai réalisé cela en utilisant cette astuce simple
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)