0

Custom Date/Time PickerDialog Android

1.Giới thiệu:

Trong bài này, mình sẽ giới thiệu cho các bạn về Time Selection trong Android. Có nhiều loại Time Selection: AnalogClock, Chronometor, DatePickerDialog, TimePickerDialog. Nhưng mình chỉ giới thiệu 2 control cuối phổ biến, các control khác các bạn tự tìm hiểu thêm trên mạng:

2.Code

Mình sẽ sử dụng mô hình MVVM trong Android. Đầu tiên tạo 1 interface riêng chứa Date/Time PickerDialog, tên là TimeManagement.java

public interface TimeManagement {
    TimeManagement dialogDatePicker(DatePickerDialog.OnDateSetListener onDateSetListener);

    void showDatePickerDialog();

    TimeManagement dialogTimePicker(TimePickerDialog.OnTimeSetListener onTimeSetListener);

    void showTimePickerDialog();
}

Tiếp theo tạo class implement interface TimeManagement để build và custom Date/Time PickerDialog, đặt tên là TimeManagementImpl.java

public class TimeManagementImpl implements TimeManagement {
    private static final String DATE_PICKER = "mDatePicker";
    private static final String DAY_FIELD = "day";
    private static final String ID = "id";
    private static final String ANDROID = "android";
    private Context mContext;
    private DatePickerDialog mDatePickerDialog;
    private TimePickerDialog mTimePickerDialog;
    private Calendar mCalendar;

    public DialogManagerImpl(Context context) {
        mContext = context;
        mCalendar = Calendar.getInstance();
        }
        
    @Override
    public TimeManagement dialogDatePicker(DatePickerDialog.OnDateSetListener onDateSetListener) {
        mDatePickerDialog =
                new DatePickerDialog(mContext, onDateSetListener, mCalendar.get(Calendar.YEAR),
                        mCalendar.get(Calendar.MONTH), mCalendar.get(Calendar.DAY_OF_MONTH));
        return this;
    }

    @Override
    public void showDatePickerDialog() {
        if (mDatePickerDialog == null) {
            return;
        }
        mDatePickerDialog.show();
    }

    @Override
    public TimeManagement dialogTimePicker(TimePickerDialog.OnTimeSetListener onTimeSetListener) {
        mTimePickerDialog = new TimePickerDialog(mContext, onTimeSetListener,
                mCalendar.get(Calendar.HOUR_OF_DAY), mCalendar.get(Calendar.MINUTE), true);
        return this;
    }

    @Override
    public void showTimePickerDialog() {
        if (mTimePickerDialog == null) {
            return;
        }
        mTimePickerDialog.show();
    }
    }

Tại class ViewModel, implements DatePickerDialog.OnDateSetListener (Với Datepicker) (hay TimePickerDialog.OnTimeSetListener(Với TimePicker)).

//DatePicker Dialog, tương tự đối với TimePicker Dialog
@Override
    public void onDateSet(DatePicker view, int year, int month, int dayOfMonth) {
        setDate(String.valueOf(new StringBuilder().append(date).append("/").append(month).append("/").append(year).append("")));
    }
    
 // Even onClick
     public void onPickDate(View view) {
        mTimeManagement.showDatePickerDialog();
    }

Bạn có 5 theme có thể lựa chọn cho Date/Time Picker Dialog: mDatePickerDialog = new DatePickerDialog(mContext, X, onDateSetListener, mCalendar.get(Calendar.YEAR), mCalendar.get(Calendar.MONTH), mCalendar.get(Calendar.DAY_OF_MONTH)); Thay vào X lần lượt các giá trị, ta sẽ được như hình minh họa

  1. THEME_DEVICE_DEFAULT_LIGHT
  2. AlertDialog.THEME_DEVICE_DEFAULT_DARK
  3. AlertDialog.THEME_HOLO_DARK
  4. AlertDialog.THEME_HOLO_LIGHT
  5. AlertDialog.THEME_TRADITIONAL

3. Custom

Đối với các theme HOLO hay TRADITIONAL, ta có thể custom để chỉ hiển thị tháng và năm, hoặc chỉ năm, như sau : Tại method buid dialog như đã nói ở trên, ta tiến hành bổ sung như sau

 @Override
    public TimeManagement dialogDatePicker(DatePickerDialog.OnDateSetListener onDateSetListener) {
        mDatePickerDialog =
                new DatePickerDialog(mContext, onDateSetListener, mCalendar.get(Calendar.YEAR),
                        mCalendar.get(Calendar.MONTH), mCalendar.get(Calendar.DAY_OF_MONTH));
                        
                        try {
            Field[] datePickerDialogFields = mDatePickerDialog.getClass().getDeclaredFields();
            for (Field datePickerDialogField : datePickerDialogFields) {
                if (datePickerDialogField.getName().equals("mDatePicker")) {
                    datePickerDialogField.setAccessible(true);
                    DatePicker datePicker =
                            (DatePicker) datePickerDialogField.get(mDatePickerDialog);
                    if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
                        int daySpinnerId =
                                Resources.getSystem().getIdentifier("day", "id", "android");
                        if (daySpinnerId != 0) {
                            View daySpinner = datePicker.findViewById(daySpinnerId);
                            if (daySpinner != null) {
                            //Ẩn cột date, chỉ còn lại month và year
                                daySpinner.setVisibility(View.GONE);
                            }
                        }
                    }
                }
            }
        } catch (IllegalAccessException e) {
            Log.e(TAG, "IllegalAccessException: ", e);
        }
        return this;
    }

Code trên mình đã ẩn đi cột date, bạn có thể ẩn với month hay year nếu muốn, TimePicker cũng tương tự như vậy. Chúc thành công


All rights reserved

Viblo
Hãy đăng ký một tài khoản Viblo để nhận được nhiều bài viết thú vị hơn.
Đăng kí