Подтвердить что ты не робот

Разрешить внешнее касание для DialogFragment

У меня есть Fragment в моем приложении, которое показывает DialogFragment.
У меня в фрагменте кнопка, которая закрывает диалог. Но когда я показываю dialogFragment, прикосновения вне диалогового окна ничего не делают, и я не могу щелкнуть по кнопкам вне диалогового фрагмента.

Как разрешить внешние касания для DialogFragment?

4b9b3361

Ответ 1

Для этого необходимо включить флаг Window, который разрешает внешнее касание, и для хорошего внешнего вида должен быть очищен флаг фона. Поскольку это необходимо сделать после создания диалога, я внедрил его с помощью Handler.

@Override
public void onViewCreated(final View view, Bundle savedInstanceState) {
    super.onViewCreated(view, savedInstanceState);

    // This is done in a post() since the dialog must be drawn before locating.
    getView().post(new Runnable() {

        @Override
        public void run() {

            Window dialogWindow = getDialog().getWindow();

            // Make the dialog possible to be outside touch
            dialogWindow.setFlags(WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL,
                    WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL);
            dialogWindow.clearFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND);

            getView().invalidate();
        }
    });
}

В этот момент возможен внешний контакт.

Если мы хотим сделать его более приятным и без фрейма, можно добавить следующий код:

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    // Hide title of the dialog
    setStyle(STYLE_NO_FRAME, 0);
}

Ответ 2

Это более общий флаг, позволяющий любому действию не только касаться действий

window.setFlags(WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
        WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE);

Ответ 3

Я нашел альтернативный способ справиться с увольнением при прикосновении снаружи. Пожалуйста, проверьте ниже пример кода, который определенно будет работать,

@Override
public void onStart() {
    // mDialogView is member variable
    mDialogView = getView();
    mDialogView.setOnTouchListener(new View.OnTouchListener() {

        @Override
        public boolean onTouch(View v, MotionEvent event) {
            float eventX = event.getRawX();
            float eventY = event.getRawY();

            int location[] = new int[2];
            mDialogView.getLocationOnScreen(location);

            if (eventX < location[0] || eventX > (location[0] + mDialogView.getWidth()) || eventY < location[1]
                    || eventY > location[1] + mDialogView.getHeight()) {
                dismiss();
                return true;
            }
            return false;
        }
    });
}

В моем случае я получал getDialog() как ненулевое значение, но getDialog(). Устранение() не работает. Кроме того, решение, помеченное как указано выше, также не работает в моем случае. Итак, я принял этот подход.

Ответ 4

Вам нужно установить подходящий стиль для ваших нужд. Подробнее о стилях для FragmentDialogs вы можете прочитать в официальных документах .

Я считаю, что вы можете использовать следующий стиль:

  • STYLE_NO_FRAME

Ответ 5

Ну, пусть будет конкретным. Если вы хотите работать с внешними представлениями, вам не следует использовать фрагмент диалога, используйте вместо этого фрагмент.

 FragmentTransaction transaction = fragmentManager.beginTransaction();
    // For a little polish, specify a transition animation
    transaction.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN);
    // To make it fullscreen, use the 'content' root view as the container
    // for the fragment, which is always the root view for the activity
    transaction.add(android.R.id.content, newFragment)
               .addToBackStack(null).commit();

И сделайте макет wrap_content, который, по-видимому, будет выглядеть как Dialog, и по умолчанию он помещается в верхней части экрана.

Подробнее см. здесь

Ответ 6

@yaniv предоставил ответ. Но в случае, если вы хотите, вот фрагмент, где вы получите тот же результат, но без необходимости публиковать Runnable в корневом View:

@NonNull
@Override
public Dialog onCreateDialog(@Nullable final Bundle savedInstanceState) {
    final Dialog dialog = super.onCreateDialog(savedInstanceState);
    dialog.getWindow().addFlags(WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL);
    return dialog;
}