Android에서 CustomDialog 만들기

2024. 8. 27. 11:22·Android

0️⃣ CustomDialog!

사실 Dialog를 띄워 화면에 알림을 주는 일은 이제는 도저히 뺄 수 없는 필수 기능이다. 할 줄 안다고 생각했는데도 막상 다시 하니 또 버벅거리며 한참을 헤매서 세세하게 기록해보려고 한다.

1️⃣ dialog.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"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@color/black_a50"
    android:gravity="center"
    android:paddingHorizontal="20dp">

    <androidx.constraintlayout.widget.ConstraintLayout
        android:layout_width="match_parent"
        android:layout_height="192dp"
        android:background="@drawable/shape_dialog"
        android:paddingHorizontal="20dp"
        android:paddingVertical="14dp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent">

        <TextView
            android:id="@+id/tv_dialog_title"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:gravity="center"
            android:text="@string/dialog_default"
            android:textColor="@color/white"
            android:textSize="16sp"
            android:textStyle="bold"
            app:layout_constraintBottom_toTopOf="@+id/wrapper_buttons"
            app:layout_constraintLeft_toLeftOf="parent"
            app:layout_constraintRight_toRightOf="parent"
            app:layout_constraintTop_toTopOf="parent" />

        <LinearLayout
            android:id="@+id/wrapper_buttons"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="horizontal"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent">

            <androidx.appcompat.widget.AppCompatButton
                android:id="@+id/btn_dialog_cancel"
                style="@style/detail_btn"
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_marginEnd="4dp"
                android:layout_weight="1"
                android:backgroundTint="@color/transparent"
                android:gravity="center"
                android:text="@string/dialog_cancel"
                android:textColor="@color/blue_grey"
                app:layout_constraintBottom_toBottomOf="parent"
                app:layout_constraintStart_toStartOf="parent" />

            <androidx.appcompat.widget.AppCompatButton
                android:id="@+id/btn_dialog_confirm"
                style="@style/detail_btn"
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_marginStart="4dp"
                android:layout_weight="1"
                android:gravity="center"
                android:text="@string/dialog_confirm"
                android:textAllCaps="false"
                app:layout_constraintBottom_toBottomOf="@+id/btn_dialog_cancel"
                app:layout_constraintEnd_toEndOf="parent"
                app:layout_constraintStart_toEndOf="@+id/btn_dialog_cancel"
                app:layout_constraintTop_toTopOf="@+id/btn_dialog_cancel" />

        </LinearLayout>

    </androidx.constraintlayout.widget.ConstraintLayout>

</androidx.constraintlayout.widget.ConstraintLayout>

핵심 포인트는 가장 최상단 부모 태그의 width, height값을 match_parent로 주는 것이다.

2️⃣ DialogFragment

class TwoButtonDialogFragment(
    private val title: String,
    private val onClickConfirm: () -> Unit
) : DialogFragment() {
    private var _binding: DialogTwobuttonBinding? = null
    val binding get() = _binding!!

    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View {
        _binding = DialogTwobuttonBinding.inflate(inflater, container, false)
        return binding.root
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        initView()
    }

    private fun initView() = with(binding) {
        tvDialogTitle.text = title

        btnDialogCancel.setOnClickListener {
            dismiss()
        }

        btnDialogConfirm.setOnClickListener {
            onClickConfirm()
            dismiss()
        }
    }


    override fun onResume() {
        super.onResume()
        // full Screen code
        dialog?.window?.setLayout(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT)
        dialog?.window?.setBackgroundDrawable(ColorDrawable(Color.TRANSPARENT))
        dialog?.window?.clearFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND)
    }
}

해당 Fragment를 재사용하기 위해 생성자로 title과 setOnClickListner를 받아와서 사용했다.

또한 onResume() 코드를 전체 복사해서 붙여넣자! 그렇지 않으면 아래 스크린샷처럼 옹졸한 Dialog가 나온다... (옹졸 그자체)

3️⃣ Dialog 띄우는 함수

btn.setOnClickListener {
    val dialog = TwoButtonDialogFragment(
        getString(R.string.timer_dialog_finish)
    ) {
        // timer 종료하기
    }
    // 알림창이 띄워져있는 동안 배경 클릭 막기
    dialog.isCancelable = false
    dialog.show(getParentFragmentManager(), "ConfirmDialog")
}

이렇게 setOnClickListener에서 dialog를 선언해주고, 생성자로 받기로 한 props들을 모두 보내준 뒤, show해주면 된다.

그럼 이렇게 완벽한 Dialog가 등장한다.

 


막상 정리해놓고 보니 별 거 없는데 또 저 옹졸하게 나오는 dialog 때문에 40분 넘게 삽질했다...!

더 열심히 공부해보는 것으로...

저작자표시 비영리 (새창열림)

'Android' 카테고리의 다른 글

Android에서 Firebase Google Login 구현하기  (0) 2024.08.31
Hilt로 Context 사용하기 (feat. OkHttpClient cache)  (0) 2024.08.29
Android의 4대 구성요소 알아보기  (0) 2024.08.14
Android에서 Fragment와 TabLayout, 그리고 RecyclerView 적용하기  (0) 2024.08.05
Android에서 Lottie Animation 적용하기  (0) 2024.07.04
'Android' 카테고리의 다른 글
  • Android에서 Firebase Google Login 구현하기
  • Hilt로 Context 사용하기 (feat. OkHttpClient cache)
  • Android의 4대 구성요소 알아보기
  • Android에서 Fragment와 TabLayout, 그리고 RecyclerView 적용하기
깨비도
깨비도
그림 그리는 개발자의 인디게임 생존기 & Flutter 연구소
  • 깨비도
    KKEVi.log()
    깨비도
  • 전체
    오늘
    어제
    • 전체 (98) N
      • 인디게임 개발일지 (6) N
      • C# (1)
      • Dart (3)
      • Flutter (24)
        • 문제해결 (14)
      • Kotlin (12)
      • Android (22)
        • 문제해결 (11)
      • CS (10)
        • Network (1)
      • 알고리즘 (10)
        • 코딩테스트 (10)
      • etc (10)
        • Git (1)
        • React (1)
  • 블로그 메뉴

    • 방명록
  • 링크

    • 그림 전문 일지
  • 공지사항

  • 인기 글

  • 태그

    ram
    OS
    when
    게임아트
    Firebase
    네트워크
    context
    DART
    MacOS
    인디게임
    게임개발
    stack
    Unity이펙트
    2D아트워크
    DartVM
    Gemini
    XML
    인디게임개발
    thread
    flutter
    게임기획
    Dear.MyMarionette
    IOS
    유니티
    C#
    플랫포머_배경
    Kotlin
    플러터
    CS
    Android
  • 최근 댓글

  • hELLO· Designed By정상우.v4.10.5
깨비도
Android에서 CustomDialog 만들기
상단으로

티스토리툴바