DialogFragment Dialog 영역 밖에 버튼 만들기

이지훈·2022년 3월 4일
1
post-thumbnail

다음과 같은 화면이 있다고 가정하자. 아마 리스트뷰의 어떤 아이템을 클릭했을때 보여지는 상세화면으로 판단된다. 가운데에는 카드처럼 생긴 DialogFragment가 띄워져있고 DialogFragment 바깥으로 생성하기(Register) 버튼과 X(Cancel) 버튼이 존재한다.

이와 같이 DialogFramgnet 영역밖에 버튼을 어떻게 구현해줘야할까, 독립적인 버튼만 있는 뷰를 DialogFragment가 띄워질때 동시에 띄워야 할까? 아니다.

영역 크기에 대해 훼이크를 걸어주면된다.

실제 다이얼로그의 크기는 모든 버튼을 포함하는 좀 더 큰 영역이다!

대충 이정도

하늘색으로 표시한 영역을 전체 영역의 크기로 잡고 버튼들을 만들어주고 카드뷰를 전체 영역 내부에 넣어주면 된다. 그리고 바깥의 background를 투명하게 설정하면 만들고자했던 레이아웃을 만들어낼 수 있다.

예시 코드는 다음과 같다.

framgment.xml

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 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:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@android:color/transparent">

    <androidx.constraintlayout.widget.ConstraintLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <ImageView
            android:id="@+id/iv_update_cancel"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="48dp"
            android:layout_marginEnd="24dp"
            android:src="@drawable/ic_cancel"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintTop_toTopOf="parent"
            tools:ignore="ContentDescription" />

        <androidx.cardview.widget.CardView
            android:id="@+id/cv_update"
            android:layout_width="296dp"
            android:layout_height="444dp"
            app:cardCornerRadius="48dp"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent">

            <androidx.constraintlayout.widget.ConstraintLayout
                android:id="@+id/cl_update"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:background="@drawable/bg_dialog_rounded">

                <androidx.appcompat.widget.Toolbar
                    android:id="@+id/tb_update"
                    android:layout_width="0dp"
                    android:layout_height="wrap_content"
                    android:layout_marginTop="32dp"
                    android:backgroundTint="@color/purple_200"
                    android:elevation="0dp"
                    app:layout_constraintEnd_toEndOf="parent"
                    app:layout_constraintStart_toStartOf="parent"
                    app:layout_constraintTop_toTopOf="parent"
                    app:popupTheme="@style/ThemeOverlay.AppCompat.Light"
                    app:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar">

                    <EditText
                        android:id="@+id/et_update_regionNickname"
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:layout_marginStart="32dp"
                        android:background="@null"
                        android:inputType="text"
                        android:shadowColor="#000000"
                        android:shadowDx="1"
                        android:shadowDy="1"
                        android:shadowRadius="5"
                        android:text="@string/region"
                        android:textColor="@color/white"
                        android:textSize="20sp"
                        app:layout_constraintStart_toStartOf="parent"
                        app:layout_constraintTop_toTopOf="parent" />

                </androidx.appcompat.widget.Toolbar>

                <TextView
                    android:id="@+id/tv_update_date"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_marginStart="32dp"
                    android:layout_marginTop="6dp"
                    android:shadowColor="#000000"
                    android:shadowDx="1"
                    android:shadowDy="1"
                    android:shadowRadius="5"
                    android:text="@string/date"
                    android:textColor="#DBDBDB"
                    android:textSize="14sp"
                    app:layout_constraintStart_toStartOf="parent"
                    app:layout_constraintTop_toBottomOf="@id/tb_update" />

                <ImageView
                    android:id="@+id/iv_update_image"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:contentDescription="@string/play"
                    android:src="@drawable/ic_image"
                    app:layout_constraintBottom_toBottomOf="parent"
                    app:layout_constraintEnd_toEndOf="parent"
                    app:layout_constraintStart_toStartOf="parent"
                    app:layout_constraintTop_toTopOf="parent" />

                <EditText
                    android:id="@+id/et_update_comment"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:layout_marginStart="32dp"
                    android:layout_marginEnd="32dp"
                    android:layout_marginBottom="131dp"
                    android:background="@null"
                    android:inputType="text"
                    android:shadowColor="#000000"
                    android:shadowDx="1"
                    android:shadowDy="1"
                    android:shadowRadius="5"
                    android:singleLine="true"
                    android:text="@string/comment"
                    android:textColor="@color/white"
                    android:textSize="20sp"
                    app:layout_constraintBottom_toBottomOf="parent"
                    app:layout_constraintStart_toStartOf="parent" />

                <TextView
                    android:id="@+id/tv_update_music_name"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:layout_marginStart="32dp"
                    android:layout_marginEnd="32dp"
                    android:layout_marginBottom="84dp"
                    android:ellipsize="marquee"
                    android:marqueeRepeatLimit="marquee_forever"
                    android:shadowColor="#000000"
                    android:shadowDx="1"
                    android:shadowDy="1"
                    android:shadowRadius="5"
                    android:singleLine="true"
                    android:text="@string/music_title"
                    android:textColor="@color/white"
                    android:textSize="20sp"
                    app:layout_constraintBottom_toBottomOf="parent"
                    app:layout_constraintStart_toStartOf="parent" />

                <TextView
                    android:id="@+id/tv_update_artist"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:layout_marginStart="32dp"
                    android:layout_marginEnd="32dp"
                    android:layout_marginBottom="55dp"
                    android:ellipsize="marquee"
                    android:marqueeRepeatLimit="marquee_forever"
                    android:shadowColor="#000000"
                    android:shadowDx="1"
                    android:shadowDy="1"
                    android:shadowRadius="5"
                    android:singleLine="true"
                    android:text="@string/artist"
                    android:textColor="#DBDBDB"
                    android:textSize="20sp"
                    app:layout_constraintBottom_toBottomOf="parent"
                    app:layout_constraintStart_toStartOf="parent" />

                <TextView
                    android:id="@+id/tv_update_music_reference"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_marginStart="32dp"
                    android:layout_marginBottom="32dp"
                    android:shadowColor="#000000"
                    android:shadowDx="1"
                    android:shadowDy="1"
                    android:shadowRadius="5"
                    android:text="@string/music_reference"
                    android:textColor="#C3C3C3"
                    android:textSize="14sp"
                    app:layout_constraintBottom_toBottomOf="parent"
                    app:layout_constraintStart_toStartOf="parent" />

                <ProgressBar
                    android:id="@+id/pb_update"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:visibility="gone"
                    app:layout_constraintBottom_toBottomOf="parent"
                    app:layout_constraintEnd_toEndOf="parent"
                    app:layout_constraintStart_toStartOf="parent"
                    app:layout_constraintTop_toTopOf="parent" />

            </androidx.constraintlayout.widget.ConstraintLayout>
        </androidx.cardview.widget.CardView>

        <androidx.appcompat.widget.AppCompatButton
            android:id="@+id/btn_update"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="24dp"
            android:background="@drawable/bg_update_round"
            android:text="@string/update_complete"
            android:textColor="@color/black"
            android:textStyle="bold"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toBottomOf="@id/cv_update" />

    </androidx.constraintlayout.widget.ConstraintLayout>

</androidx.constraintlayout.widget.ConstraintLayout>

해당 fragment(DialogFragment) 의 코드

전체 화면을 차지하지않고 특정한 크기를 맞춰줘야 하기때문에
onResume() 내부에서 dialog의 height와 width 를 설정해주었다.

 override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View {
        _binding = FragmentUpdateDotBinding.inflate(inflater, container, false)

        fragment = activity?.supportFragmentManager?.findFragmentByTag("UpdateDotFragment")!!

        // 타이틀 바 제거
        dialog?.requestWindowFeature(Window.FEATURE_NO_TITLE)
        // 다이얼로그 radius 적용
        dialog?.window?.setBackgroundDrawable(ColorDrawable(Color.TRANSPARENT))

        showProgress()

        initData()

        return binding.root
    }

override fun onResume() {
        super.onResume()

        val windowManager =
            requireContext().getSystemService(Context.WINDOW_SERVICE) as WindowManager

        val width: Int
        val height: Int

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
            defaultDisplay = requireContext().display!!

            val windowMetrics = windowManager.currentWindowMetrics
            val windowInsets: WindowInsets = windowMetrics.windowInsets

            val insets = windowInsets.getInsetsIgnoringVisibility(
                WindowInsets.Type.navigationBars() or WindowInsets.Type.displayCutout()
            )
            val insetsWidth = insets.right + insets.left
            val insetsHeight = insets.top + insets.bottom

            val b = windowMetrics.bounds

            width = b.width() - insetsWidth
            height = b.height() - insetsHeight
        } else {
            @Suppress("DEPRECATION")
            defaultDisplay = windowManager.defaultDisplay

            val size = Point()

            @Suppress("DEPRECATION")
            defaultDisplay.getSize(size)

            width = size.x
            height = size.y
        }

        dialog!!.window!!.setLayout(width, height)
    }

Reference)
DialogFragment 영역 밖 버튼 만들기
Place a button outside my layout on DialogFragment

화면 전체 사이즈 구하기
DialogFragment의 size(width, height)조절

DialogFramgent 관련 Deprecated 해결
Getter for defaultDisplay: Display!' is deprecated. Deprecated in Java

getSize() deprecated in API level 30

DialogFragment 띄우기
안드로이드 Fragment에서 Dialog 띄우기 ==> DialogFragment

DialogFragment 종료시키기
DialogFragment의 dismiss 질문입니다.

profile
실력은 고통의 총합이다. Android Developer

0개의 댓글