DialogFragment를 올바르게 닫는 방법은 무엇입니까?


121

문서 dismiss()Dialog클래스 의 메소드에 대해 다음과 같이 말합니다 .

이 대화 상자를 닫고 화면에서 제거합니다. 이 메서드는 모든 스레드에서 안전하게 호출 할 수 있습니다. 대화 상자가 닫힐 때 정리를 수행하기 위해이 메서드를 재정의해서는 안되며 대신 onStop().

내 코드에서 내가하는 일은 getDialog().dismiss()그것을 기각하라는 전화 뿐이다. 그러나 나는 다른 일을하거나 사용하지 않습니다 onStop(). 따라서 DialogFragment메모리 누수 등을 피하기 위해 a 를 올바르게 해제하는 방법을 정확히 묻고 있습니다 .

답변:


197

tl; dr : a를 닫는 올바른 방법 은 DialogFragment에서 직접DialogFragment 사용 dismiss() 하는 것 입니다.


세부 정보 : DialogFragment 상태 문서

대화 상자를 직접 호출하는 것이 아니라 여기에서 API를 통해 대화 상자를 제어 (표시, 숨기기, 닫기시기 결정)해야합니다.

따라서 대화 상자에서getDialog().dismiss() 호출되므로을 사용해서는 안됩니다 . 대신 DialogFragment 자체 의 메서드를 사용해야합니다.dismiss() dismiss()

공개 무효 dismiss ()

조각과 대화 상자를 닫습니다. 조각이 백 스택에 추가 된 경우이 항목을 포함한 모든 백 스택 상태가 표시됩니다. 그렇지 않으면 조각을 제거하기 위해 새 트랜잭션이 커밋됩니다.

보시다시피, 이것은 대화 상자를 닫을뿐만 아니라 프로세스와 관련된 프래그먼트 트랜잭션을 처리합니다.

onStop수동 정리 (파일 닫기, 커서 닫기 등)가 필요한 리소스를 명시 적으로 만든 경우 에만 사용해야 합니다. 그럼에도 불구 하고 기본 대화 상자가 onStop아닌 DialogFragment를 재정의 합니다 onStop.


1
@ScootrNova : 안됩니다. 아마 다른 곳에 버그가있을 것입니다. 조각을 어떻게 만들고 있습니까?
Heinzi

protected void showDialogFragment(final DialogFragment fragment) {final FragmentTransaction fTransaction = getSupportFragmentManager().beginTransaction(); fTransaction.addToBackStack(null); fragment.show(fTransaction, "dialog");} 불쾌한 한 라이너에 대해 죄송합니다! 하지만 네가 옳을 수 있으므로 당분간 DialogFragments를 닫는 다른 방법을 작성했습니다. dismiss () 메서드를 사용하여 그들을 해제하는 방법은 태그로 조각을 찾은 다음 null이 아닌 경우 dismiss ()를 실행하는 것입니다. 오, 그래, 나는 new그 메소드에 전달하기 직전에 조각을 처리하고 있습니다.
Charles Madere

2
@ScootrNova : 흠, 그게 잘못된 건 아니에요. 다른 한편으로는 호환성 라이브러리를 사용한 적이 없어서 확신 할 수 없습니다. 최소한의 독립적 인 예제를 만들고 그것에 대해 새로운 질문을 시작하는 것이 합리적 일 수 있습니다.
Heinzi

그 당시 @CharlesMadere, 해결책을 찾았습니까?
JCarlosR

죄송합니다 @JCarlos, 이것은 몇 년 전이었습니다, 확실하지 않습니다.
Charles Madere

76

a를 닫는 더 좋은 방법 DialogFragment은 다음과 같습니다.

Fragment prev = getSupportFragmentManager().findFragmentByTag("fragment_dialog");
if (prev != null) {
    DialogFragment df = (DialogFragment) prev;
    df.dismiss();
}

이렇게하면에 대한 참조를 유지할 필요가 없으며 DialogFragment모든 곳에서 닫을 수 있습니다.


7

이 코드 만 사용하는 것은 어떨까요?

dismiss();

자체적으로 Dialog Fragment를 닫으려면. 이 코드를 대화 상자를 닫으려는 대화 조각 안에 간단히 넣을 수 있습니다.

예를 들면 :

button.setOnClickListener(new View.OnClickListener() {
   @Override
   public void onClick(View v) {
       dismiss();
   }
});

그러면 화면에 표시된 최근 대화 조각이 닫힙니다.

도움이되기를 바랍니다.


항상 작동하지 않음
Mahmoud Heretani

5

나는 Terel의 답변에 찬성 투표를했습니다. Kotlin 사용자를 위해 이것을 게시하고 싶었습니다.

supportFragmentManager.findFragmentByTag(TAG_DIALOG)?.let {
    (it as DialogFragment).dismiss()
}

간단한 코드가 열심히 작동합니다. 업데이트 친구에게 감사드립니다 !!
Ayush Katuwal

4

Kotlin 버전 의 Terel 답변

(fragmentManager.findFragmentByTag(TAG) as? DialogFragment)?.dismiss()

1

당신은 당신을 해고해야 DialogonPause()그래서 우선합니다.

또한 닫기 전에 null아래 스 니펫과 같이 확인할 수 있으며 표시됩니다.

@Override
protected void onPause() {
    super.onPause();
    if (dialog != null && dialog.isShowing()) {
        dialog.dismiss();
    }
}

그는 이미 dismiss () 및 DialogFragment에 대한 내용을 작성했습니다.
Paresh Mayani

난 둘 다 대화와 DialogFragments @PareshMayani이 작품을 생각한다
Venky

2
@PareshMayani가 올바른 Venky라고 생각합니다. DialogFragmentGoogle 의 튜토리얼 onPause()은 사용되는 방법을 전혀 보여주지 않습니다 . 하지만 당신이 뭘하는지 알 것 같아요. 사용자가 전화하지 않으면 요점은 무엇입니까 onPause()? 시스템이 조각이 호출되고 있음을 알 때입니다. 사용자가 언제 취소한다고 말하면 어떨까요? 이 경우 닫는 더 좋은 방법은 무엇입니까?
Andy

1

다른 답변 에는 공식 문서 ( DialogFragment Reference )에 대한 참조가 있지만 거기에 제공된 예제에 대한 언급은 없습니다.

void showDialog() {
    mStackLevel++;

    // DialogFragment.show() will take care of adding the fragment
    // in a transaction.  We also want to remove any currently showing
    // dialog, so make our own transaction and take care of that here.
    FragmentTransaction ft = getFragmentManager().beginTransaction();
    Fragment prev = getFragmentManager().findFragmentByTag("dialog");
    if (prev != null) {
        ft.remove(prev);
    }
    ft.addToBackStack(null);

    // Create and show the dialog.
    DialogFragment newFragment = MyDialogFragment.newInstance(mStackLevel);
    newFragment.show(ft, "dialog");
}

이렇게하면 현재 표시된 대화 상자가 제거되고 인수가있는 새 DialogFragment가 만들어지고 백 스택에 새 상태로 표시됩니다. 트랜잭션이 팝되면 현재 DialogFragment 및 해당 Dialog가 파괴되고 이전 DialogFragment (있는 경우)가 다시 표시됩니다. 이 경우 DialogFragment는 Dialog의 트랜잭션을 팝핑하는 것을 처리 할 것이며 Dialog와는 별도로 해제됩니다.

내 필요에 따라 다음과 같이 변경했습니다.

FragmentManager manager = getSupportFragmentManager();
Fragment prev = manager.findFragmentByTag(TAG);
if (prev != null) {
    manager.beginTransaction().remove(prev).commit();
}

MyDialogFragment fragment = new MyDialogFragment();
fragment.show(manager, TAG);

1

다른 답변에 추가하면 DialogFragment전체 화면 호출 dismiss()이있는 경우 조각 백 스택에서 DialogFragment가 표시되지 않습니다. 해결 방법은 onBackPressed()상위 활동 을 호출 하는 것입니다.

이 같은:

CustomDialogFragment.kt

closeButton.onClick {
    requireActivity().onBackPressed()
}

하루를 저장하십시오. 감사합니다
Mahmoud Heretani

0

해제하려는 조각에서 dismiss ()를 호출하면됩니다.

imageView3.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            dismiss();
        }
    });

0

내 프래그먼트가 <fragment>태그 (전체 화면 dialogfragment의 경우) 를 사용하여 탐색 그래프에 정의되었을 때 dialogfragment가 dismiss()명령으로 닫히지 않음을 발견했습니다 . 대신 백 스택을 팝해야했습니다.

findNavController(getActivity(), R.id.nav_host_fragment).popBackStack();

그러나 동일한 dialogfragment가 <dialog>태그 를 사용하여 탐색 그래프에 정의 된 경우 제대로 dismiss()작동합니다.


0
CustomFragment dialog = (CustomDataFragment) getSupportFragmentManager().findFragmentByTag("Fragment_TAG");
if (dialog != null) {
  dialog.dismiss();
}
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.