BottomSheetDialogFragment에서 fragment replace시, 잘못된 container에 배치되는 문제

Dialog 를 사용할 때, 다이어로그 내에서도 프래그먼트 전환을 해야하는 경우가 있다. (튜토리얼 구성이라던가 단계별 UI를 구성해야 하는 경우.

일반적으로 이런식의 코드를 작성할 수 있다.

childFragmentManager.beginTransaction().replace(R.id.container, fragment).commit()

잘 작동할것 처럼 보이지만, BottomSheetDialogFragment 내 에서 위 코드 처럼 작성한다면, 아래 사진 처럼 의도하지 않은 위치에 Fragment가 배치된다.

문제가 생긴 Dialog

해결 방법은 간단하다. Fragment가 위치하고자 하는 container의 ID를 “container” 이외의 것으로 교체하자.

childFragmentManager.beginTransaction().replace(R.id.fragment_container, fragment).commit()

다음과 같은식으로..

문제가 해결된 Dialog

원인이 무엇일까? 바로 해당 라이브러리에서 이미 저 “container” 라는 ID를 사용중이다. 보통 Fragment가 위치하는 레이아웃의 이름을 “container”나 “fragment_container” 식으로 명명하기 일수인데 나도 모르게 라이브러리단의 container를 참조한 모양이다. 아무리 검색해봐도 같은 문제를 겪는 사람을 보지 못해서 BottomSheetDialogFragment 구현부를 뒤졌다.

그렇게 찾아낸 라이브러리 내부의 design_bottom_sheet_dialog.xml

<FrameLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/container"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:fitsSystemWindows="true">

  <androidx.coordinatorlayout.widget.CoordinatorLayout
      android:id="@+id/coordinator"
      android:layout_width="match_parent"
      android:layout_height="match_parent"
      android:fitsSystemWindows="true">

    <View
        android:id="@+id/touch_outside"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:focusable="false"
        android:importantForAccessibility="no"
        android:soundEffectsEnabled="false"
        tools:ignore="UnusedAttribute"/>

    <FrameLayout
        android:id="@+id/design_bottom_sheet"
        style="?attr/bottomSheetStyle"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_gravity="center_horizontal|top"
        app:layout_behavior="@string/bottom_sheet_behavior"/>

  </androidx.coordinatorlayout.widget.CoordinatorLayout>

</FrameLayout>

보다시피 최상위에 위치한 FrameLayout의 id가 “container”인 것을 볼 수 있다.

Leave a comment

Your email address will not be published. Required fields are marked *