나는 개인적으로 안드로이드 기본 다이얼로그 디자인을 선호하지 않는다..💦 저 상태에서 기본 색상을 변경하더라도 알림창 하나로 APP 전체적인 디자인 컨셉을 흩트릴 수도 있다는 생각에 기본 알림창 다이얼로그를 전부 커스텀하기로 결정했다.
만들어 볼 커스텀 다이얼로그이다. 여러 페이지(activity, fragment)에 쓰일 수 있도록 TextView는 고정 문구가 아니라 파라미터로 전달 받은 문구를 넣어줄 예정이다 ❗
먼저 dialog_confirm.xml
파일을 작성한다. Button
스타일은 필자가 따로 정의해놓은거라서 원하는 스타일로 디자인해주면 된다.
dialog_confirm.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@drawable/view_round_white_6"
android:gravity="center"
android:minWidth="300dp"
android:orientation="vertical"
android:padding="20dp">
<TextView
android:id="@+id/confirmTextView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:minHeight="50dp"
android:textSize="14sp"
tools:text="확인창입니다." />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="20dp"
android:orientation="horizontal">
<Button
android:id="@+id/noButton"
style="@style/MainOutlineButton"
android:layout_width="0dp"
android:layout_height="40dp"
android:layout_marginEnd="7dp"
android:layout_weight="1"
android:text="취소"
android:textSize="14sp" />
<Button
android:id="@+id/yesButton"
style="@style/MainFillButton"
android:layout_width="0dp"
android:layout_height="40dp"
android:layout_weight="1"
android:text="확인"
android:textSize="14sp" />
</LinearLayout>
</LinearLayout>
만약 테두리를 둥글게 하고 싶다면 drawable에 아래 파일을 작성해 dialog_confirm.xml
의 최상위 레이아웃 background
로 적용시켜주면 된다.
view_round_white_6.xml
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="@color/white" />
<corners android:radius="6dp" />
</shape>
필자는 삭제할 id 값을 넘겨주어야 했기 때문에 파라미터로 id 값을 넣어주었지만, 간단히 activity 종료를 한다거나 dismiss() 정도만 원한다면 파라미터를 받을 필요 없다.
단순히 다이얼로그 종료 dismiss()
만 원한다면 아래 Dialog 클래스 내의 정의로 끝낼 수 있지만, activity 종료 finish()
를 원한다면 인터페이스를 통해 해당 activity에 액션을 정의해주어야한다.
class ConfirmDialog(
confirmDialogInterface: ConfirmDialogInterface,
text: String, id: Int
) : DialogFragment() {
// 뷰 바인딩 정의
private var _binding: DialogPackageDeleteBinding? = null
private val binding get() = _binding!!
private var confirmDialogInterface: ConfirmDialogInterface? = null
private var text: String? = null
private var id: Int? = null
init {
this.text = text
this.id = id
this.confirmDialogInterface = confirmDialogInterface
}
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View {
_binding = DialogPackageDeleteBinding.inflate(inflater, container, false)
val view = binding.root
// 레이아웃 배경을 투명하게 해줌, 필수 아님
dialog?.window?.setBackgroundDrawable(ColorDrawable(Color.TRANSPARENT))
binding.confirmTextView.text = text
// 취소 버튼 클릭
binding.noButton.setOnClickListener {
dismiss()
}
// 확인 버튼 클릭
binding.yesButton.setOnClickListener {
this.confirmDialogInterface?.onYesButtonClick(id!!)
dismiss()
}
return view
}
override fun onDestroyView() {
super.onDestroyView()
_binding = null
}
}
interface ConfirmDialogInterface {
fun onYesButtonClick(id: Int)
}
원하는 activity 또는 fragment에서 커스텀한 다이얼로그 및 인터페이스를 정의해주면 끝!
여기서 하나 짚고 넘어갈 것 🙋🏻♀️
dialog.show(manager: FragmentManager, tag: String) 호출 시, manager로 넘겨줄 값 !
- activity ➡
this.supportFragmentManager
- fragment ➡
activity?.supportFragmentManager!!
class MainActivity : AppCompatActivity(), ConfirmDialogInterface {
private lateinit var binding: ActivityMainBinding
...
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root)
clickViewEvents()
}
// 뷰 클릭 이벤트 정의
private fun clickViewEvents() {
// 삭제 버튼 클릭
binding.deleteButton.setOnClickListener {
val dialog = ConfirmDialog(this, "패키지를 삭제하시겠습니까?", pkgId)
// 알림창이 띄워져있는 동안 배경 클릭 막기
dialog.isCancelable = false
dialog.show(this.supportFragmentManager, "ConfirmDialog")
}
}
override fun onYesButtonClick(id: Int) {
// 액티비티 종료를 원한다면 finish()를 호출해주면 되겠죵 :)
deletePackageApiCall(id)
}
}