본문 바로가기

안드로이드/코틀린

[And/Kotlin] Numberpicker를 활용한 생년월일 선택 뷰 만들기

반응형
  • 최초 작성 : 2020/10/13 
  • numberpicker input type 수정 : 2020/10/23
  • numberpicker editText 값 가져오기 포스팅 추가 : 2021/03/23

 

기본적으로 제공하는 Datapicker와 DatepickerDialog를 활용해서 날짜 선택 화면을 만들 수 있습니다. spnnier 와 calendar 2가지중 적합한 UI를 선택할 수 있습니다. ( 개인적으로 이쁜건 spnnier라고 생각하고 조금 더 신경쓴(?) 느낌입니다. ) 

위 - spnnier / 아래 - calendar

<?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:orientation="vertical"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <DatePicker
        android:id="@+id/dpSpinner"
        android:datePickerMode="spinner"
        android:calendarViewShown="false"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"/>
    <DatePicker
        android:id="@+id/dpCalendar"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"/>

</LinearLayout>

datepickermode와 calednarViewshown 옵션으로 간단하게 spinner와 calendar 설정이 가능하다.

하지만 간혹 커스텀된 UI로(아래 사진 참고) 날짜를 선택해야할 경우가 있는데 그럴땐 Numberpicker를 활용하면 간단하게 구현 가능합니다. Numberpicker는 스트링 배열을 spinner 형태로 보여주는 뷰로써 해당 예제 외에 문자열들을 선택하는 뷰를 만들때도 유용하게 사용됩니다.

예시

        var yearList = (1950..2020).toList()
        var monthList = (1..12).toList()
        var dateList = (1..31).toList()

        var yearStrConvertList = yearList.map { it.toString() }
        var monthStrConvertList = monthList.map { it.toString() }
        var dateStrConvertList = dateList.map { it.toString() }

        npYear.run {
            minValue = 0
            maxValue = yearStrConvertList.size - 1
            wrapSelectorWheel = false
            displayedValues = yearStrConvertList.toTypedArray()
        }

        npMonth.run {
            minValue = 0
            maxValue = monthStrConvertList.size - 1
            wrapSelectorWheel = false
            displayedValues = monthStrConvertList.toTypedArray()
        }

        npDay.run {
            minValue = 0
            maxValue = dateStrConvertList.size - 1
            wrapSelectorWheel = false
            displayedValues = dateStrConvertList.toTypedArray()
        }

map을 이용해 Int 배열을 String 배열로 변환해 displayedValues에 대입하면 커스텀된 날짜 선택 뷰가 완성됩니다. 조금 더 이쁜(?) 뷰가 완성 됐네요 ㅎㅎ

 

옵션

wrapSelectorWheel : default 값은 true로 false시 picker의 범위가 시작 ~ 끝으로 고정됩니다. 아래 예제 년도는 false 값이고 월은 true 값입니다.

descendantFocusability : picker는 기본적으로 데이터를 클릭하면 edittext로 전환되어 특정 값을 입력할 수 있는데 해당 값을 'NumberPicker.FOCUS_BLOACK_DESCENDANTS' 로 변경하면 edittext로 전환을 막을 수 있습니다.

 

colorControlNormal : style을 통해 divider 색을 변경할 수 있는 옵션입니다.  그외 글씨 크기, 하이라이트된 글자 색상등을 아래와 같이 수정할 수 있습니다.

    <style name="AppTheme.Picker" parent="Theme.AppCompat.Light.NoActionBar">
        <item name="android:textColorPrimary">@color/colorPrimaryDark</item>
        <item name="colorControlNormal">@color/colorPrimaryDark</item>
        <item name="android:textColorHighlight">@color/colorPrimaryDark</item>
        <item name="android:textSize">20dp</item>
    </style>

입력타입 변경 ( 추가 - 2020/10/23 )

numberPicker는 기본적으로 string 배열을 받기 때문에 값 입력시 문자 작성이 가능한 키보드를 띄우는데, 년도 입력시 숫자 키보드를 띄우주는게 사용자 경험상 좋게 남겨질 수 있습니다. 

 npYear.run {
			....        
            findInput(this)?.inputType = InputType.TYPE_CLASS_NUMBER
        }
        
        
        
    private fun findInput(viewGroup: ViewGroup): EditText? {
        var childCount = viewGroup.childCount
        for (i in 0 until childCount) {
            var childView = viewGroup.getChildAt(i)
            if (childView is ViewGroup) {
                findInput(childView)
            } else if (childView is EditText) {
                return childView
            }

        }

        return null
    }

 

 

 

해당 포스팅은 지극히 주관적인 내용으로 저자의 복기 목적으로 작성된 것이고, 내용에대해 수정이나 추가 요청은 언제든 환영합니다. 

반응형