우선 CustomDialog를 디자인 할 XML을 만들어줍니다.
저는 Dialog에 RadioButton이 있고, 이 RadioButton으로 선택한 다음 확인을 누르면 그 값을 전달하게끔 설계했습니다.
<?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="wrap_content"
android:layout_gravity="center"
android:background="@drawable/round10_white" <!-- 둥근 모서리 xml -->
android:orientation="vertical">
<TextView
android:id="@+id/dialog_title"
android:layout_width="match_parent"
android:layout_height="50dp"
android:layout_gravity="center_horizontal"
android:ellipsize="end"
android:gravity="center"
android:letterSpacing="@dimen/letter_spacing" <!-- 간격 설정 -->
android:maxLines="1"
android:paddingStart="15dp"
android:paddingEnd="15dp"
android:text="커스텀 다이얼로그"
android:textColor="@color/black"
android:textSize="17dp"
android:textStyle="bold"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<View
android:id="@+id/view"
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="@color/black"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/dialog_title" />
<RadioGroup
android:id="@+id/radio_group"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="25dp"
android:layout_marginTop="5dp"
android:layout_marginBottom="20dp"
app:layout_constraintBottom_toTopOf="@+id/dialog_button"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/dialog_title"></RadioGroup>
<LinearLayout
android:id="@+id/dialog_button"
android:layout_width="match_parent"
android:layout_height="50dp"
android:orientation="horizontal"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="@+id/gift_radio_group">
<TextView
android:id="@+id/dialog_cancel"
android:layout_width="0dp"
android:layout_height="50dp"
android:layout_weight="1"
android:background="@drawable/button_round10" <!-- 둥근 모서리 버튼 xml -->
android:gravity="center"
android:letterSpacing="@dimen/letter_spacing"
android:text="취소"
android:textColor="@color/greyish_brown"
android:textSize="18dp"
android:textStyle="bold" />
<TextView
android:id="@+id/dialog_confirm"
android:layout_width="0dp"
android:layout_height="50dp"
android:layout_weight="1"
android:background="@drawable/button_round10_redpink" <!-- 둥근 모서리 버튼 xml -->
android:gravity="center"
android:letterSpacing="@dimen/letter_spacing"
android:text="확인"
android:textColor="@color/white"
android:textSize="18dp"
android:textStyle="bold" />
</LinearLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
RadioGroup만 생성해주고 RadioButton은 동적으로 생성할 것입니다.
저는 Fragment에서 Dialog를 생성해서 Interface를 활용한 Listener로 값을 주고받게끔 할 것입니다.
우선 CustomDialog Class를 작성합니다.
private class CustomDialog(
context: Context,
private var curPos: Int,
) : AppCompatDialog(context, R.style.CustomDialog), DialogInterface {
private lateinit var binding: CustomDialogBinding
private var confirmListener: ((Int) -> Unit)? = null
private var cancelListener: (() -> Unit)? = null
var pos = curPos
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = CustomDialogBinding.inflate(layoutInflater)
val view = binding.root
setContentView(view)
// 로컬에서 선택할 값 배열 생성
val selectArray: ArrayList<String> = arrayListOf("택1", "택2", "택3", "택4")
val radioGroup = binding.radioGroup
for (i in 0..selectArray.size-1) {
var radio = RadioButton(view.context).apply {
id = i
text = selectArray[i]
setTextColor(Color.BLACK)
setPadding(pxToDp(5),0,0,0)
val layoutParam = RadioGroup.LayoutParams(
ViewGroup.LayoutParams.WRAP_CONTENT,
pxToDp(30)
)
layoutParam.setMargins(0,pxToDp(15),0,0)
layoutParams = layoutParam
}
radioGroup.addView(radio)
}
radioGroup.check(pos)
binding.dialogConfirm.setOnClickListener {
pos = radioGroup.checkedRadioButtonId
this.confirmListener?.invoke(pos)
}
binding.dialogCancel.setOnClickListener {
this.cancelListener?.invoke()
}
}
fun setConfirmListener(confirmListener: ((Int) -> Unit)? = null) {
this.confirmListener = confirmListener
}
fun setCancelListener(cancelListener: (() -> Unit)? = null) {
this.cancelListener = cancelListener
}
fun pxToDp(value: Int) : Int {
return TypedValue.applyDimension(
TypedValue.COMPLEX_UNIT_DIP,
value.toFloat(),
context.resources.displayMetrics
).toInt()
}
}
setConfirmListener와 setCancelListener를 통해 리스너를 등록할 수 있습니다.
배열을 생성하여 Radio Button을 동적으로 생성할 수 있습니다.
마진같은 경우는 LayoutParam을 통해 설정해줍니다.
확인버튼을 눌렀을 때 체크되어 있는 값을 invoke해줍니다.
object DialogBuilder {
fun showCustomDialog(context: Context, curPos: Int, confirmListener: ((Int) -> Unit)? = null, cancelListener: (() -> Unit)? = null) {
val dialog = CustomDialog(
context = context,
curPos = curPos ?: 0,
)
dialog.setConfirmListener {
confirmListener?.invoke(dialog.pos)
dialog.dismiss()
}
dialog.setCancelListener {
cancelListener?.invoke()
dialog.dismiss()
}
dialog.show()
}
}
다이얼로그 빌더를 object로 하여 만들어줍니다.
앞으로 다이얼로그를 생성할 때 이 빌더를 통해 만들어줄 수 있습니다.
이제 Activity 또는 Fragment에서 다이얼로그를 만들어 표현할 수 있습니다.
private fun showCustomDialog(pos: Int) {
DialogBuilder.showCustomDialog(requireContext(),
curPos = pos,
confirmListener = {
Log.d("TEST", "selected $it")
},
cancelListener = {
null
}
)
}
showCustomDialog에 현재의 pos를 넣어주면, 다이얼로그 빌더를 통해 CustomDialog를 생성하고 RadioGroup에서 RadioButton이 동적으로 생성되며 현재의 pos가 체크되어 있게끔 생성될 것입니다.
그리고 확인을 눌렀을 때 체크되어 있는 곳의 pos가 confirmListener를 통해 돌아와 Log를 찍어냅니다.
이를 활용하면 무궁무진한 다이얼로그 활동을 할 수 있겠죠? ㅎㅎ
'안드로이드 > 기능구현' 카테고리의 다른 글
Kotlin invoke의 개념과 사용법 그리고 예시 (0) | 2022.09.26 |
---|---|
웹뷰 PIP 자체 구현해보기 [ AOS 기능구현 ] (0) | 2022.07.25 |