問題描述
如何收聽 BottomSheetDialogFragment
的最終解除?我只想在最終解雇時保存用戶更改...
How can I listen to a FINAL dismissal of a BottomSheetDialogFragment
? I want to save user changes on the final dismissal only...
我嘗試了以下操作:
方法一
只有在通過向下滑動對話框(不是在后按或觸摸外部)關閉對話框時才會觸發
This only fires, if the dialog is dismissed by swiping it down (not on back press or on touch outside)
@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;
}
方法二
這讓我無法區分最終解雇和來自屏幕旋轉或活動娛樂的解雇...
This does not allow me to distinguish between a final dismissal and one that is coming from a screen rotation or activity recreation...
@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();
}
問題
如何收聽表明用戶已完成對話的事件?
How can I listen to an event that indicates, that the user has finished the dialog?
推薦答案
雖然關于 SO 的所有類似問題都建議使用 onDismiss
我認為以下是正確的解決方案:
Although all similar questions on SO suggest using onDismiss
I think following is the correct solution:
@Override
public 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
這不會觸發:
* on screen rotation and activity recreation
解決方案
結合 onCancel 和 BottomSheetBehavior.BottomSheetCallback.onStateChanged,如下所示:
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();
}
}
這篇關于BottomSheetDialogFragment - 聽用戶事件解除的文章就介紹到這了,希望我們推薦的答案對大家有所幫助,也希望大家多多支持html5模板網!