numberPicker custom
class BottomSheetResDialog(
context: Context,
title: String,
private val resList: Array<Restaurant>,
positiveButtonClickListener: (String, String) -> (Unit)
) : BottomSheetDialog(context) {
private var binding = BottomSheetMenuDialogBinding.inflate(layoutInflater)
private var selectedRestaurant = resList[0].name // spinner의 setSelection같은 느낌을 주고 싶었다.
private var selectedMenu = resList[0].menus[0] // 다이어로그가 만들어질때 맨 첫 레스토랑의 맨 첫 메뉴가 선택되어있는것 처럼 구현
init {
binding.tvTitle.text = title
val resNameList = resList.map { it.name }.toTypedArray()
//식당 피커
binding.resPicker.apply {
this.wrapSelectorWheel = false // 순환 false
this.maxValue = resList.size - 1
this.minValue = 0
this.displayedValues = resNameList //보여줄 string 값 array<String>
this.descendantFocusability =
NumberPicker.FOCUS_BLOCK_DESCENDANTS //editText가 눌리는 것을 막는다.
//descendantFocusability > 뷰에 포커스가 갈 때 뷰그룹과 자식들간의 관계를 정의
//FOCUS_BLOCK_DESCENDANTS > 자식들(editText 겟지?)의 포커스를 막는다.
this.setOnValueChangedListener { _, _, newVal ->
selectedRestaurant = resNameList[newVal] //식당이 바뀌면
setMenuPicker(newVal) //메뉴피커를 세팅한다. newVal이 새로 선택된 값의 index임
}
}
setMenuPicker(0) //다이어로그가 만들어질 때 메뉴는 설정된 값이 없으므로 첫번째 식당의 메뉴를 세팅하도록 설정
binding.buttonPositive.setOnClickListener {
positiveButtonClickListener(selectedRestaurant, selectedMenu)
dismiss()
}
setContentView(binding.root)
}
private fun setMenuPicker(resIndex: Int) {
val menuList = resList[resIndex].menus //선택된 레스토랑의 메뉴리스트
binding.menuPicker.apply {
this.displayedValues = null //menuPicker의 displayedValues가 바뀌는데 , 그냥 바로 바꿔주면 에러가 나더라..
// 그래서 displayedValues를 null로 한번 clear하고 다시 새로운 메뉴 array를 세팅해줌
this.wrapSelectorWheel = false
this.maxValue = menuList.size - 1
this.minValue = 0
this.displayedValues = menuList
this.descendantFocusability = NumberPicker.FOCUS_BLOCK_DESCENDANTS
this.setOnValueChangedListener { _, _, newVal ->
selectedMenu = menuList[newVal] //새롭게 선택된 메뉴
}
this.value = minValue
//A식당의 3번째 메뉴 >> B식당으로 바꿈>> B식당의 3번째 메뉴가 보여져있음.
//B식당의 첫번째 메뉴를 보여주고 싶어서 menuPicker의 value를 minValue로 설정해줌
//menuPicker만들 때 디폴트 값 같은 너낌.
}
}
class Builder(
private var context: Context,
private var title: String,
private var resList: Array<Restaurant>,
private var positiveButtonClickListener: (String, String) -> (Unit)
) {
fun setTitle(title: String): Builder {
this.title = title
return this
}
fun setPicker(resList: Array<Restaurant>): Builder {
this.resList = resList
return this
}
fun build(): BottomSheetDialog {
return BottomSheetResDialog(
context,
title,
resList,
positiveButtonClickListener
)
}
}
}
class ActivityTextInputLayoutCustom : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val a = Restaurant("김밥천국", arrayOf("참치김밥", "떡볶이", "라면", "돈가스"))
val b = Restaurant("롤링파스타", arrayOf("고르곤졸라피자", "오일파스타", "명란크림파스타"))
val c = Restaurant("뼈다귀해장국", arrayOf("뼈다귀해장국", "편육"))
BottomSheetResDialog.Builder(this, "식당고르기", arrayOf(a, b, c), ::listener).build().show()
}
private fun listener(res: String, menu: String) {}
}
data class Restaurant(
val name: String,
val menus : Array<String>
)
<?xml version="1.0" encoding="utf-8"?>
<androidx.appcompat.widget.LinearLayoutCompat 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:orientation="vertical"
android:paddingBottom="34dp">
<androidx.appcompat.widget.LinearLayoutCompat
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<androidx.appcompat.widget.LinearLayoutCompat
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:paddingTop="12dp">
<androidx.appcompat.widget.AppCompatTextView
android:id="@+id/tvTitle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:gravity="center"
tools:text="식당 검색" />
<Space
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginEnd="36dp"
android:layout_weight="1" />
</androidx.appcompat.widget.LinearLayoutCompat>
</androidx.appcompat.widget.LinearLayoutCompat>
<androidx.appcompat.widget.LinearLayoutCompat
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<NumberPicker
android:id="@+id/resPicker"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginEnd="16dp"
android:layout_weight="1"
android:theme="@style/AppTheme.Picker" />
<NumberPicker
android:id="@+id/menuPicker"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginEnd="16dp"
android:layout_weight="1"
android:theme="@style/AppTheme.Picker" />
//theme을 만들어서 커스텀 합니다.
</androidx.appcompat.widget.LinearLayoutCompat>
<androidx.appcompat.widget.AppCompatButton
android:id="@+id/buttonPositive"
android:layout_width="match_parent"
android:layout_height="40dp"
android:layout_marginStart="16dp"
android:layout_marginEnd="16dp"
android:background="@color/purple_200"
android:gravity="center"
android:text="검색" />
</androidx.appcompat.widget.LinearLayoutCompat>
<style name="AppTheme.Picker" parent="Theme.AppCompat.Light.NoActionBar">
<item name="android:textColorPrimary">@color/purple_200</item> //글자 색
<item name="android:colorControlNormal">@color/yellow</item> //divider color
<item name="android:textStyle">bold</item>
<item name="android:textSize">16sp</item>
</style>