앱에 선택 도구 추가

Compose 사용해 보기
Jetpack Compose는 Android를 위한 권장 UI 도구 키트입니다. Compose에서 구성요소를 추가하는 방법을 알아보세요.

Android에서 제공하는 컨트롤로 사용자는 시간이나 날짜를 바로 사용 가능한 대화상자로 선택할 수 있습니다. 이러한 선택 도구는 시간 (시, 분, 오전/오후)이나 날짜 (년, 월, 일)의 각 부분을 선택하는 컨트롤을 제공합니다.

material.io의 시간 선택 도구 예
그림 1. 모바일 캘린더 선택 도구에서 시간 선택

이러한 선택 도구를 사용하면 사용자가 유효하고 올바르게 형식이 지정되었으며 사용자의 언어로 조정된 시간이나 날짜를 선택할 수 있습니다.

material.io의 모달 날짜 선택기 예시
그림 2. 모달 날짜 선택도구

DialogFragment를 사용하여 각 시간 또는 날짜 선택 도구를 호스팅하는 것이 좋습니다. DialogFragment는 대화상자 수명 주기를 관리하며, 핸드셋의 기본 대화상자나 대형 화면의 레이아웃에 삽입된 부분과 같이 다양한 레이아웃 구성에서 선택 도구를 표시할 수 있도록 합니다.

시간 선택 도구 만들기

DialogFragment를 사용하여 TimePickerDialog를 표시하려면 DialogFragment를 확장하는 프래그먼트 클래스를 정의하고 프래그먼트의 onCreateDialog() 메서드에서 TimePickerDialog를 반환합니다.

시간 선택 도구의 DialogFragment 확장

TimePickerDialogDialogFragment를 정의하려면 다음을 실행합니다.

  • TimePickerDialog의 인스턴스를 반환하도록 onCreateDialog() 메서드를 정의합니다.
  • TimePickerDialog.OnTimeSetListener 인터페이스를 구현하여 사용자가 시간을 설정할 때 콜백을 수신합니다.

예를 들면 다음과 같습니다.

Kotlin

class TimePickerFragment : DialogFragment(), TimePickerDialog.OnTimeSetListener {

    override fun onCreateDialog(savedInstanceState: Bundle): Dialog {
        // Use the current time as the default values for the picker.
        val c = Calendar.getInstance()
        val hour = c.get(Calendar.HOUR_OF_DAY)
        val minute = c.get(Calendar.MINUTE)

        // Create a new instance of TimePickerDialog and return it.
        return TimePickerDialog(activity, this, hour, minute, DateFormat.is24HourFormat(activity))
    }

    override fun onTimeSet(view: TimePicker, hourOfDay: Int, minute: Int) {
        // Do something with the time the user picks.
    }
}

자바

public static class TimePickerFragment extends DialogFragment
                            implements TimePickerDialog.OnTimeSetListener {

    @Override
    public Dialog onCreateDialog(Bundle savedInstanceState) {
        // Use the current time as the default values for the picker.
        final Calendar c = Calendar.getInstance();
        int hour = c.get(Calendar.HOUR_OF_DAY);
        int minute = c.get(Calendar.MINUTE);

        // Create a new instance of TimePickerDialog and return it.
        return new TimePickerDialog(getActivity(), this, hour, minute,
                DateFormat.is24HourFormat(getActivity()));
    }

    public void onTimeSet(TimePicker view, int hourOfDay, int minute) {
        // Do something with the time the user picks.
    }
}

생성자 인수에 관한 자세한 내용은 TimePickerDialog 클래스를 참조하세요.

이제 이 프래그먼트의 인스턴스를 활동에 추가하는 이벤트만 있으면 됩니다.

시간 선택 도구 표시

위 예와 같이 DialogFragment를 정의한 후 DialogFragment의 인스턴스를 만들고 show() 메서드를 호출하여 시간 선택 도구를 표시할 수 있습니다.

예를 들어 탭하면 메서드를 호출하여 대화상자를 표시하는 다음과 같은 버튼이 있습니다.

<Button
    android:id="@+id/pickTime"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="Pick time" />

사용자가 이 버튼을 탭하면 시스템은 다음 메서드를 호출합니다.

Kotlin

findViewById<Button>(R.id.pickTime).setOnClickListener {
    TimePickerFragment().show(supportFragmentManager, "timePicker")
}

자바

findViewById<Button>(R.id.pickTime).setOnClickListener {
    TimePickerFragment().show(supportFragmentManager, "timePicker");
}

이 메서드는 위 예에 정의된 DialogFragment의 새 인스턴스에서 show()를 호출합니다. show() 메서드에는 FragmentManager의 인스턴스와 프래그먼트의 고유한 태그 이름이 필요합니다.

날짜 선택 도구 만들기

DatePickerDialog를 만드는 것은 TimePickerDialog를 만드는 것과 같습니다. 차이점은 개발자가 만드는 프래그먼트 대화상자입니다.

DialogFragment를 사용하여 DatePickerDialog를 표시하려면 DialogFragment를 확장하는 프래그먼트 클래스를 정의하고 프래그먼트의 onCreateDialog() 메서드에서 DatePickerDialog를 반환합니다.

날짜 선택 도구의 DialogFragment 확장

DatePickerDialogDialogFragment를 정의하려면 다음을 실행합니다.

  • onCreateDialog() 메서드를 정의하여 DatePickerDialog의 인스턴스를 반환합니다.
  • DatePickerDialog.OnDateSetListener 인터페이스를 구현하여 사용자가 날짜를 설정할 때 콜백을 수신합니다.

예를 들면 다음과 같습니다.

Kotlin

class DatePickerFragment : DialogFragment(), DatePickerDialog.OnDateSetListener {

    override fun onCreateDialog(savedInstanceState: Bundle): Dialog {
        // Use the current date as the default date in the picker.
        val c = Calendar.getInstance()
        val year = c.get(Calendar.YEAR)
        val month = c.get(Calendar.MONTH)
        val day = c.get(Calendar.DAY_OF_MONTH)

        // Create a new instance of DatePickerDialog and return it.
        return DatePickerDialog(requireContext(), this, year, month, day)

    }

    override fun onDateSet(view: DatePicker, year: Int, month: Int, day: Int) {
        // Do something with the date the user picks.
    }
}

자바

public static class DatePickerFragment extends DialogFragment
                            implements DatePickerDialog.OnDateSetListener {

    @Override
    public Dialog onCreateDialog(Bundle savedInstanceState) {
        // Use the current date as the default date in the picker.
        final Calendar c = Calendar.getInstance();
        int year = c.get(Calendar.YEAR);
        int month = c.get(Calendar.MONTH);
        int day = c.get(Calendar.DAY_OF_MONTH);

        // Create a new instance of DatePickerDialog and return it.
        return new DatePickerDialog(requireContext(), this, year, month, day);
    }

    public void onDateSet(DatePicker view, int year, int month, int day) {
        // Do something with the date the user picks.
    }
}

생성자 인수에 관한 자세한 내용은 DatePickerDialog 클래스를 참고하세요.

이 프래그먼트의 인스턴스를 활동에 추가하는 이벤트만 있으면 됩니다.

날짜 선택 도구 표시

앞의 예시와 같이 DialogFragment를 정의한 후에는 DialogFragment의 인스턴스를 만들고 show()를 호출하여 날짜 선택 도구를 표시할 수 있습니다.

예를 들어 탭하면 메서드를 호출하여 대화상자를 표시하는 다음과 같은 버튼이 있습니다.

<Button
    android:id="@+id/pickDate"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="Pick date"/>

사용자가 이 버튼을 탭하면 시스템은 다음 메서드를 호출합니다.

Kotlin

findViewById<Button>(R.id.pickDate).setOnClickListener {
    val newFragment = DatePickerFragment()
    newFragment.show(supportFragmentManager, "datePicker")
}

자바

findViewById<Button>(R.id.pickDate).setOnClickListener {
    val newFragment = DatePickerFragment();
    newFragment.show(supportFragmentManager, "datePicker");
}

이 메서드는 위 예에 정의된 DialogFragment의 새 인스턴스에서 show()를 호출합니다. show() 메서드에는 FragmentManager의 인스턴스와 프래그먼트의 고유한 태그 이름이 필요합니다.

자동 완성과 함께 선택 도구 사용

2017년 Android는 사용자가 여러 앱에서 양식을 작성하는 데 사용할 수 있는 데이터를 저장할 수 있는 자동 완성 프레임워크를 도입했습니다. 선택 도구는 사용자가 날짜 또는 시간 데이터를 저장하는 필드의 값을 변경할 수 있는 UI를 제공하여 자동 완성 시나리오에서 유용합니다. 예를 들어 신용카드 양식에서 날짜 선택 도구를 사용하면 사용자가 신용카드 만료일을 입력하거나 변경할 수 있습니다.

선택 도구는 대화상자이므로 다른 필드와 함께 활동에 표시되지 않습니다. 선택 도구가 표시되지 않을 때 선택 도구 데이터를 표시하려면 선택 도구가 표시되지 않을 때 값을 표시할 수 있는 EditText와 같은 다른 뷰를 사용하면 됩니다.

EditText 객체는 기본적으로 AUTOFILL_TYPE_TEXT 유형의 자동 완성 데이터를 예상합니다. 반대로 자동 완성 서비스는 데이터를 AUTOFILL_TYPE_DATE로 저장하여 데이터의 적절한 표시를 만들 수 있습니다. 유형의 불일치를 해결하려면 EditText에서 상속받고 AUTOFILL_TYPE_DATE 유형의 값을 올바르게 처리하는 데 필요한 메서드를 구현하는 맞춤 뷰를 만드는 것이 좋습니다.

AUTOFILL_TYPE_DATE 유형의 값을 처리할 수 있는 EditText의 서브클래스를 만들려면 다음 단계를 따르세요.

  1. EditText에서 상속받는 클래스를 만듭니다.
  2. AUTOFILL_TYPE_DATE를 반환하는 getAutofillType() 메서드를 구현합니다.
  3. getAutofillValue() 메서드를 구현하고 이 메서드는 밀리초 단위로 날짜를 표시하는 AutofillValue 객체를 반환해야 합니다. 반환 객체를 만들려면 forDate() 메서드를 사용하여 AutofillValue 객체를 생성합니다.
  4. autofill() 메서드를 구현합니다. 이 메서드는 로직을 제공하여 AUTOFILL_TYPE_DATE 유형의 AutofillValue 매개변수를 처리합니다. 매개변수를 처리하려면 올바른 문자열 표시(예: mm/yyyy)를 만듭니다. 문자열 표시를 사용하여 뷰의 text 속성을 설정합니다.
  5. 사용자가 EditText의 맞춤 서브클래스에서 날짜를 수정하려고 할 때 선택 도구를 표시하는 기능을 구현합니다. 뷰는 사용자가 선택 도구에서 선택한 값의 문자열 표시로 text 속성을 업데이트합니다.

AUTOFILL_TYPE_DATE 값을 처리하는 EditText의 서브클래스에 관한 예시는 자바 또는 Kotlin의 자동 완성 프레임워크 샘플을 참고하세요.

맞춤 뷰의 자동 완성 지원에 관한 자세한 내용은 자동 완성 프레임워크를 참고하세요.