사용자에게 결정을 내리거나 추가정보를 입력하라는 메시지를 표시하는 작은 창. 다이얼로그는 화면을 가득 채우지 않으며 보통은 사용자가 다음으로 계속 진행하기 전에 조치를 취해야 하는 모달 이벤트에 사용됨
e.g)
AlertDialog클래스를 사용하면 여러 가지 대화 상자 디자인 빌드 가능. 대개 이 다이얼로그 클래스만 있으면 되는 경우가 많음. 그림 2와 같이 알림 다이얼로그에는 세 가지 영역이 있음
선택 사항이며 콘텐츠 영역에 상세한 메시지,목록 또는 맞춤 레이아웃이 채워져 있는 경우에만 사용해야함. 단순한 메시지 또는 질문을 나타내야 하는 경우 제목은 없어도 됨
메시지,목록 또는 다른 맞춤 레이아웃을 표시 가능
DialogExample 프로젝트 생성 -> activityMain.xml 작성
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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:orientation="vertical"
android:gravity="center"
tools:context=".MainActivity">
<TextView
android:id="@+id/tv_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello World!" />
<Button
android:id="@+id/btn1_alert"
android:text="dialog"
android:layout_marginTop="20dp"
android:layout_width="200dp"
android:layout_height="wrap_content" />
<Button
android:id="@+id/btn2_custom"
android:text="custom dialog"
android:layout_marginTop="20dp"
android:layout_width="200dp"
android:layout_height="wrap_content" />
<Button
android:id="@+id/btn3_date"
android:text="Date picker dialog"
android:layout_marginTop="20dp"
android:layout_width="200dp"
android:layout_height="wrap_content" />
<Button
android:id="@+id/btn4_time"
android:text="Time picker dialog"
android:layout_marginTop="20dp"
android:layout_width="200dp"
android:layout_height="wrap_content" />
<Button
android:id="@+id/btn5_porgress"
android:text="Progress dialog"
android:layout_marginTop="20dp"
android:layout_width="200dp"
android:layout_height="wrap_content" />
</LinearLayout>
// 1. 기본 다이얼로그
binding.btn1Alert.setOnClickListener {
var builder = AlertDialog.Builder(this)
builder.setTitle("기본 다이얼로그 타이틀")
builder.setMessage("기본 다이얼로그 메세지")
builder.setIcon(R.mipmap.ic_launcher)
// 버튼 클릭시에 무슨 작업을 할 것인가!
val listener = object : DialogInterface.OnClickListener {
override fun onClick(p0: DialogInterface?, p1: Int) {
when (p1) {
DialogInterface.BUTTON_POSITIVE ->
binding.tvTitle.text = "BUTTON_POSITIVE"
DialogInterface.BUTTON_NEUTRAL ->
binding.tvTitle.text = "BUTTON_NEUTRAL"
DialogInterface.BUTTON_NEGATIVE ->
binding.tvTitle.text = "BUTTON_NEGATIVE"
}
}
}
builder.setPositiveButton("Positive", listener)
builder.setNegativeButton("Negative", listener)
builder.setNeutralButton("Neutral", listener)
builder.show()
}
// 2. 커스텀 다이얼로그
binding.btn2Custom.setOnClickListener {
val builder = AlertDialog.Builder(this)
builder.setTitle("커스텀 다이얼로그")
builder.setIcon(R.mipmap.ic_launcher)
val v1 = layoutInflater.inflate(R.layout.dialog, null)
builder.setView(v1)
// p0에 해당 AlertDialog가 들어온다. findViewById를 통해 view를 가져와서 사용
val listener = DialogInterface.OnClickListener { p0, p1 ->
val alert = p0 as AlertDialog
val edit1: EditText? = alert.findViewById<EditText>(R.id.editText)
val edit2: EditText? = alert.findViewById<EditText>(R.id.editText2)
binding.tvTitle.text = "이름 : ${edit1?.text}"
binding.tvTitle.append(" / 나이 : ${edit2?.text}")
}
builder.setPositiveButton("확인", listener)
builder.setNegativeButton("취소", null)
builder.show()
}
dialog.xml 추가
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="16dp"
android:orientation="vertical">
<EditText
android:id="@+id/editText"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:ems="10"
android:inputType="textPersonName"
android:text="Name" />
<EditText
android:id="@+id/editText2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:ems="10"
android:inputType="textPersonName"
android:text="AGE" />
</LinearLayout>
</LinearLayout>
// 3. 날짜 다이얼로그
binding.btn3Date.setOnClickListener {
val calendar = Calendar.getInstance()
val year = calendar.get(Calendar.YEAR)
val month = calendar.get(Calendar.MONTH)
val day = calendar.get(Calendar.DAY_OF_MONTH)
val listener = DatePickerDialog.OnDateSetListener { datePicker, i, i2, i3 ->
// i년 i2월 i3일
binding.tvTitle.text = "${i}년 ${i2 + 1}월 ${i3}일"
}
var picker = DatePickerDialog(this, listener, year, month, day)
picker.show()
}
// 4. 시간 다이얼로그
binding.btn4Time.setOnClickListener {
val calendar = Calendar.getInstance()
val hour = calendar.get(Calendar.HOUR)
val minute = calendar.get(Calendar.MINUTE)
val listener = TimePickerDialog.OnTimeSetListener { timePicker, i, i2 ->
binding.tvTitle.text = "${i}시 ${i2}분"
}
val picker = TimePickerDialog(this, listener, hour, minute, false) // true하면 24시간 제
picker.show()
}
// 5. 프로그레스 다이얼로그
binding.btn5Porgress.setOnClickListener {
// 권장하진 않지만 사용은 가능하다.
pro = ProgressDialog.show(this, "타이틀입니다.", "메시지입니다.")
// 핸들러를 통해서 종료 작업을 한다.
val handler = Handler()
val thread = Runnable { pro?.cancel() }
handler.postDelayed(thread, 5000) // 딜레이는 5초
}
//6. 프로그래스 다이얼로그 다른 방식. (커스텀과 비슷)
binding.btn5Porgress.setOnClickListener {
val builder = AlertDialog.Builder(this)
builder.setTitle("프로그래스바")
builder.setIcon(R.mipmap.ic_launcher)
val v1 = layoutInflater.inflate(R.layout.progressbar, null)
builder.setView(v1)
builder.show()
}
progressbar.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:orientation="vertical">
<ProgressBar
android:id="@+id/progressbar"
android:layout_width="match_parent"
android:layout_height="76dp"
android:layout_gravity="center"
android:layout_marginTop="48dp"
android:indeterminate="false"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="loading..."
android:textSize="16sp"
android:layout_marginTop="16dp"/>
</LinearLayout>
DialogFragment는 안드로이드에서 대화상자 형태의 UI를 구현할 때 사용하는 클래스. 이는 Fragment 클래스를 상속받아 모든 기능을 제공하면서, 추가로 대화상자를 관리하는 기능을 가지고 있음. DialogFragment를 사용하면 대화상자의 생명주기를 더욱 세밀하게 관리할 수 있으며, 화면 회전 같은 구성 변경 시에도 대화상자의 상태 유지 가능
DialogFragment는 여러 가지 방법으로 사용 가능. 일반적으로는 다음과 같은 용도로 사용됨
전통적인 대화상자
부모 액티비티의 컨텍스트 내에서 실행되는 내장된 프래그먼트
대화상자와 유사한 UI를 가진 전체 화면 프래그먼트
대화상자를 사용하는 전형적인 시나리오로는 사용자에게 결정을 요구하거나, 추가 정보를 입력받거나, 알림을 제공하는 등이 있음
e.g) DialogFragment 예제 코드
MyDialogFragment.kt:
kotlinCopy code
class MyDialogFragment : DialogFragment() {
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
return activity?.let {
// Use the Builder class for convenient dialog construction
val builder = AlertDialog.Builder(it)
builder.setMessage("Do you like this app?")
.setPositiveButton("Yes") { dialog, id ->
// Send the positive button event back to the host activity
}
.setNegativeButton("No") { dialog, id ->
// Send the negative button event back to the host activity
}
// Create the AlertDialog object and return it
builder.create()
} ?: throw IllegalStateException("Activity cannot be null")
}
}
이 DialogFragment는 onCreateDialog 메서드를 오버라이드하여 AlertDialog를 생성하고 구성함. 대화상자에는 메시지와 두 개의 버튼("Yes"와 "No")이 있으며, 각 버튼을 눌렀을 때의 동작은 이 예제에서는 정의되지 않았음
MainActivity.kt:
kotlinCopy code
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
// Show the dialog by calling show() method
findViewById<Button>(R.id.showDialogButton).setOnClickListener {
MyDialogFragment().show(supportFragmentManager, "MyDialogFragment")
}
}
}
MainActivity는 버튼을 클릭하면 MyDialogFragment를 표시. show 메서드는 FragmentManager와 대화상자의 태그를 인자로 받음