NumberPicker


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>