안드로이드 개발을 하다 보면 화면 위에 작은 창을 띄워 간단한 처리가 필요하다.
이런 경우 AlertDialog를 사용하고, 사용자에게 안내를 하거나 확인, 취소 버튼의 이벤트를 처리할 수 있다.
하지만 기본으로 제공되는 AlertDialog를 통해서는 사용자 입력에 대한 값을 처리할 수 없고, 디자인을 수정하기에도 제약이 있다.
이 제약사항들을 해결하고자 자주 사용하는 Custom Dialog를 소개하려고 한다.
사용방법
1. Dialog의 화면(layout)을 정의한다
2. Dialog의 클래스를 정의한다
3. 결과값을 넘겨주기 위한 리스너를 정의한다
1. Dialog의 화면(layout)을 정의한다
id, password를 입력받고 완료 처리를 위한 확인 버튼을 정의했다.
fragment_custom_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">
<EditText
android:id="@+id/editText_id"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="id"
app:layout_constraintTop_toTopOf="parent" />
<EditText
android:id="@+id/editText_password"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="password"
app:layout_constraintTop_toBottomOf="@id/editText_id" />
<Button
android:id="@+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="확인"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="@id/editText_password" />
</androidx.constraintlayout.widget.ConstraintLayout>
2. Dialog의 클래스를 정의한다
Dialog 사용을 위한 컨테이너로 DialogFragment 상속받고, onCreateDialog() 콜백 메서드에서 AlertDialog에 대한 정의를 한다.
별도의 클래스로 정의한 이유는 여러 곳에서 공통으로 사용하기 위함과 상속받은 DialogFragment가 생명주기 관리 및 별도의 처리들을 알아서 해주기 때문이다.
CustomListenerDialogFragment.kt
class CustomListenerDialogFragment : DialogFragment() {
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
return activity?.let {
val builder = AlertDialog.Builder(it)
val binding = FragmentCustomDialogBinding.inflate(it.layoutInflater)
builder.setView(binding.root).create()
} ?: throw IllegalStateException("Activity cannot be null")
}
}
3. 결과값을 넘겨주기 위한 리스너를 정의한다
id, passwrod 입력 후 확인 버튼을 클릭하면 Dialog를 실행한 Activity나 Fragment로 값을 보낸다.
interface ClickListener {
fun onClick(id: String, pw: String)
}
전체 코드
정의한 화면은 바인딩하여 사용했고, 확인버튼을 클릭하는 시점에 리스너를 통해 id, password 값을 전달했다.
Dialog를 종료하기 위해서는 작업완료 후 dismiss()를 호출해야 한다.
class CustomListenerDialogFragment(private val listener: ClickListener) : DialogFragment() {
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
println("Dialog onCreateDialog")
return activity?.let {
val builder = AlertDialog.Builder(it)
val binding = FragmentCustomDialogBinding.inflate(it.layoutInflater)
.apply {
button.setOnClickListener {
listener.onClick(
id = editTextId.text.toString(),
pw = editTextPassword.text.toString()
)
dismiss()
}
}
builder.setView(binding.root).create()
} ?: throw IllegalStateException("Activity cannot be null")
}
}
interface ClickListener {
fun onClick(id: String, pw: String)
}
Activity 또는 Fragment에서 위에서 구현한 CustomListenerDialogFragment를 구현하고 show()를 호출하면 Dialog가 실행된다.
buttonListener.setOnClickListener {
CustomListenerDialogFragment(object : ClickListener {
override fun onClick(id: String, pw: String) {
Toast.makeText(baseContext, "{$id / $pw}", Toast.LENGTH_LONG).show()
}
}).show(supportFragmentManager, "tag")
}
참고
'Android' 카테고리의 다른 글
[Android] 웹뷰 스크롤 하단에 native 버튼 위치시키는 방법 (0) | 2021.09.20 |
---|---|
[Android] Realm 데이터베이스 사용하기 (0) | 2021.09.15 |
[Android] 유용한 Plugin 소개 (JsonToKotlinClass) (0) | 2021.08.29 |
[Android] Retrofit2 사용하여 API 통신하기 (0) | 2021.08.03 |
[Android] API Key 관리 (key 쉽게 숨기는 방법) (0) | 2021.07.18 |