OnCancelListener не вызывается в DialogFragment
у меня простой AlertDialog
, который отображает список некоторых элементов и при нажатии на один из них, щелкнул элемент передается обратно в вложенный Activity
. Я также хочу выполнить некоторую обработку по умолчанию, когда пользователь отменяет диалог (используя назад) - более конкретно, я хочу передать пустую строку в деятельность в таком случае.
однако, если я помещу диалог в DialogFragment
(от пакет совместимости), то OnCancelListener
is не вызывается, когда я закрываю диалог с помощью кнопки "Назад". Что я делаю не так?
public class SelectItemDialog extends DialogFragment {
public interface Callback {
void onItemSelected(String string);
}
private static final String ARG_ITEMS = "items";
private Callback callback;
public static SelectItemDialog fromItems(Collection<String> items) {
SelectItemDialog fragment = new SelectItemDialog();
fragment.setArguments(newArguments(items));
return fragment;
}
private static Bundle newArguments(Collection<String> items) {
Bundle arguments = new Bundle();
arguments.putStringArray(ARG_ITEMS, items.toArray(new String[items.size()]));
return arguments;
}
@Override
public void onAttach(Activity activity) {
super.onAttach(activity);
callback = (Callback) activity;
}
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
final String[] items = getArguments().getStringArray(ARG_ITEMS);
return new AlertDialog.Builder(getActivity())
.setTitle(R.string.dialog_select_email_title)
.setItems(items, new OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
callback.onItemSelected(items[which]);
}
})
.setOnCancelListener(new OnCancelListener() {
@Override
public void onCancel(DialogInterface dialog) {
// this code is not executed
callback.onItemSelected("");
throw new RuntimeException("dialog cancelled");
}
})
.create();
}
}
5 ответов
это может быть связано с тем, что нет явного вызова cancel()
из кода.
The OnCancelListener документация говорит:
это будет вызываться только при отмене диалога
который, вероятно, нуждается в явном cancel()
звонок.
либо сделайте положительную / отрицательную кнопку с OnClickListener
что называет DialogInterface#cancel()
или использовать OnDismissListener()
С дополнительной проверкой на посмотрите, щелкнул ли элемент списка.
кроме того, чтобы прослушать нажатие клавиши назад и отменить диалог, Вы можете настроить OnKeyListener
, как указано в это так ответ
кроме того, как только вы настроите Диалог, было бы также неплохо использовать Dialog#setCanceledOnTouchOutside()
в случае, если пользователь нажимает вне диалогового окна.
Edit: приведенная ниже Часть-это простой способ обработки событий отмены в DialogFragment.
так как вы используете DialogFragment
этот класс имеет очень удобный способ, DialogFragment#onCancel()
, который вызывается, когда DialogFragment
отменено. Делай свою логику.
DialogFragments более сложны, с несколько иным жизненным циклом, чем обычные диалоги. Поэтому сначала проверьте документацию, если у вас есть определенный Dialog
подход, который вы пытаетесь порт DialogFragment
некоторые методы, которые позволит ваш новый реализация для правильной работы!
Если вы используете DialogFragment и хотите прослушать кнопку назад, а затем использовать это -
this.getDialog().setOnKeyListener(new Dialog.OnKeyListener() {
@Override
public boolean onKey(DialogInterface dialog, int keyCode,
KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_BACK) {
if (****) {
your logic
}
return true;
}
return false;
}
});
Примечание: DialogFragment собственный диалог.setOnCancelListener и диалог.setOnDismissListener обратных вызовов. Вы не должны устанавливать их сами.
чтобы узнать об этих событиях, переопределите onCancel(DialogInterface) и onDismiss (DialogInterface).
public class SelectItemDialog extends DialogFragment {
@Override
public void onDismiss(DialogInterface dialog) {
super.onDismiss(dialog);
//your code hear
dialog.cancel();
}
}
и вы должны удалить .setOnCancelListener()
на самом деле, если вы хотите использовать DialogFragment
, вы не можете добавить OnCancelListener
или OnDismissListener
к нему, так как фрагмент диалога владеет обратными вызовами к этим методам!
у вас есть 3 варианта:
1-перейти с регулярными диалогами.
2-Установите фрагмент диалогового окна в cancellable (false) и добавьте кнопку Отмена в диалоговое окно.
3 - проверить @Nikhil Pingle ответ.
это из документации диалогового фрагмента
* <p><em>Note: DialogFragment own the {@link Dialog#setOnCancelListener
* Dialog.setOnCancelListener} and {@link Dialog#setOnDismissListener
* Dialog.setOnDismissListener} callbacks. You must not set them yourself.</em>
* To find out about these events, override {@link #onCancel(DialogInterface)}
* and {@link #onDismiss(DialogInterface)}.</p>
отменить прослушиватель или отклонить прослушиватель в DialogFragment может достичь onDismiss
DialogFragment newFragment = new DatePickerFragment();
newFragment.show(getFragmentManager(), "datePicker");
newFragment.onDismiss(new DialogInterface(){
@Override
public void cancel() {
// TODO Auto-generated method stub
}
@Override
public void dismiss() {
// TODO Auto-generated method stub
}
});