Thêm bộ chọn vào ứng dụng

Android cung cấp các chế độ kiểm soát để người dùng chọn ngày hoặc giờ các hộp thoại dễ sử dụng. Những công cụ chọn này cung cấp quyền kiểm soát để chọn từng thời gian (giờ, phút, sáng/chiều) hoặc ngày (tháng, ngày, năm).

Ví dụ về bộ chọn giờ trong material.io
Hình 1. Chọn giờ trong bộ chọn lịch trên thiết bị di động.

Việc sử dụng những bộ chọn này sẽ giúp đảm bảo rằng người dùng của bạn có thể chọn ngày hoặc giờ hợp lệ, có định dạng chính xác và được điều chỉnh theo ngôn ngữ của người dùng.

Ví dụ về bộ chọn ngày theo chế độ Material.io
Hình 2. Bộ chọn ngày cửa sổ phụ.

Bạn nên dùng DialogFragment để lưu trữ từng bộ chọn ngày hoặc giờ. DialogFragment quản lý vòng đời của hộp thoại và cho phép bạn hiển thị bộ chọn theo bố cục khác nhau các cấu hình sẵn có, chẳng hạn như trong hộp thoại cơ bản trên điện thoại di động hoặc dưới dạng một phần được nhúng của bố cục trên màn hình lớn.

Tạo bộ chọn giờ

Để hiển thị TimePickerDialog bằng DialogFragment, hãy xác định lớp mảnh mở rộng DialogFragment rồi trả về một TimePickerDialog từ của mảnh onCreateDialog() .

Mở rộng DialogFragment cho bộ chọn giờ

Để xác định DialogFragment cho TimePickerDialog, hãy làm như sau:

  • Định nghĩa phương thức onCreateDialog() để trả về một bản sao của TimePickerDialog
  • Triển khai TimePickerDialog.OnTimeSetListener để nhận lệnh gọi lại khi người dùng đặt thời gian.

Ví dụ:

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.
    }
}

Java

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.
    }
}

Hãy xem lớp TimePickerDialog để biết thông tin về đối số hàm khởi tạo.

Bây giờ, bạn chỉ cần một sự kiện thêm phiên bản của mảnh này vào của bạn.

Hiển thị bộ chọn giờ

Sau khi bạn xác định một DialogFragment như trong phần trước Ví dụ: bạn có thể hiển thị bộ chọn giờ bằng cách tạo một phiên bản của DialogFragment và gọi phương thức show() .

Ví dụ: đây là một nút mà khi được nhấn, sẽ gọi một phương thức để hiển thị hộp thoại:

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

Khi người dùng nhấn vào nút này, hệ thống sẽ gọi phương thức sau:

Kotlin

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

Java

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

Phương thức này gọi show() trên một thực thể mới của DialogFragment được xác định trong ví dụ trước. Chiến lược phát hành đĩa đơn Phương thức show() yêu cầu một bản sao của FragmentManager và tên thẻ duy nhất cho phân đoạn.

Tạo bộ chọn ngày

Tạo một DatePickerDialog giống như tạo TimePickerDialog. Điểm khác biệt là hộp thoại bạn tạo cho phân đoạn.

Cách hiển thị DatePickerDialog bằng DialogFragment: xác định lớp mảnh mở rộng DialogFragment và trả về một DatePickerDialog trong onCreateDialog() của mảnh .

Mở rộng DialogFragment cho bộ chọn ngày

Để xác định DialogFragment cho DatePickerDialog, hãy làm như sau:

  • Định nghĩa phương thức onCreateDialog() để trả về một bản sao của DatePickerDialog
  • Triển khai DatePickerDialog.OnDateSetListener để nhận lệnh gọi lại khi người dùng đặt ngày.

Ví dụ:

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.
    }
}

Java

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.
    }
}

Xem DatePickerDialog để biết thông tin về các đối số hàm khởi tạo.

Bạn chỉ cần một sự kiện thêm phiên bản của mảnh này vào của bạn.

Hiện bộ chọn ngày

Sau khi bạn xác định DialogFragment như ví dụ trước, bạn có thể hiển thị bộ chọn ngày bằng cách tạo một phiên bản của DialogFragment và gọi show().

Ví dụ: đây là một nút mà khi được nhấn, sẽ gọi một phương thức để hiển thị hộp thoại:

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

Khi người dùng nhấn vào nút này, hệ thống sẽ gọi phương thức sau:

Kotlin

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

Java

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

Phương thức này gọi show() trên một thực thể mới của DialogFragment được xác định trong ví dụ trước. Chiến lược phát hành đĩa đơn Phương thức show() cần có một bản sao của FragmentManager và tên thẻ duy nhất cho phân đoạn.

Sử dụng bộ chọn với tính năng tự động điền

Vào năm 2017, Android đã giới thiệu Khung tự động điền, cho phép người dùng lưu dữ liệu có thể dùng để điền vào biểu mẫu trong các ứng dụng khác nhau. Bộ chọn có thể hữu ích trong các tình huống tự động điền bằng cách cung cấp một giao diện người dùng cho phép người dùng thay đổi giá trị của trường lưu trữ dữ liệu ngày hoặc giờ. Ví dụ: khi thanh toán bằng thẻ tín dụng biểu mẫu, bộ chọn ngày cho phép người dùng nhập hoặc thay đổi ngày hết hạn của thẻ tín dụng.

Vì bộ chọn là hộp thoại nên sẽ không xuất hiện trong một hoạt động cùng với các trường khác. Để hiển thị dữ liệu bộ chọn khi bộ chọn không xuất hiện, bạn có thể sử dụng một khung hiển thị khác, chẳng hạn như EditText, có thể hiển thị giá trị khi bộ chọn không hiển thị.

Đối tượng EditText vốn dự kiến sẽ có dữ liệu tự động điền thuộc loại AUTOFILL_TYPE_TEXT Ngược lại, các dịch vụ tự động điền sẽ lưu dữ liệu dưới dạng AUTOFILL_TYPE_DATE để tạo cách trình bày phù hợp. Để giải quyết sự không nhất quán trong bạn nên tạo chế độ xem tuỳ chỉnh kế thừa từ EditText và triển khai các phương thức cần thiết để xử lý đúng cách các giá trị thuộc loại AUTOFILL_TYPE_DATE.

Hãy làm theo các bước sau để tạo lớp con của EditText có thể xử lý các giá trị thuộc loại AUTOFILL_TYPE_DATE:

  1. Tạo lớp kế thừa từ EditText.
  2. Triển khai getAutofillType() trả về AUTOFILL_TYPE_DATE.
  3. Triển khai getAutofillValue() , phương thức này sẽ trả về một AutofillValue đối tượng đại diện cho ngày theo mili giây. Cách tạo dữ liệu trả về hãy sử dụng phương diện forDate() để tạo một đối tượng AutofillValue.
  4. Triển khai autofill() . Phương thức này cung cấp logic để xử lý Tham số AutofillValue, thuộc loại AUTOFILL_TYPE_DATE Để xử lý thông số này, hãy tạo một chuỗi biểu thị của tập dữ liệu đó, chẳng hạn như mm/yyyy. Sử dụng chuỗi biểu diễn để đặt thuộc tính text của khung hiển thị.
  5. Triển khai chức năng hiển thị bộ chọn khi người dùng muốn chỉnh sửa ngày trong lớp con tuỳ chỉnh của EditText. Chế độ xem sẽ cập nhật thuộc tính text có một chuỗi biểu diễn giá trị mà người dùng chọn trên bộ chọn.

Ví dụ về một lớp con của EditText xử lý AUTOFILL_TYPE_DATE giá trị, hãy xem mẫu Khung tự động điền trong Java hoặc Kotlin.

Để tìm hiểu thêm về cách chứng minh tính năng tự động điền cho thành phần hiển thị tuỳ chỉnh, hãy xem Khung tự động điền.