Showing posts with label android. Show all posts
Showing posts with label android. Show all posts

Monday, February 15, 2016

[Android] Thư viện TimePicker & DatePicker đẹp cho android.

Qua một thời gian sử dụng Google calendar mình thấy cách chọn thời gian để đặt sự kiện, ghi nhớ rất dễ hiểu và trực quan. Bạn hãy xem cách Time/Date Picker của Google hoạt động trên Google calendar.
Qua một thời gian search trên Google để tìm thư viện mã nguồn mở về cách lựa chọn thời gian giống như trên mình có tìm thấy android-betterpickers.
Dưới đây là hình ảnh về Time/Date Picker thư viện hỗ trợ.

Sau đây mình sẽ hướng dẫn các bạn thêm thư viện vào trong project bằng Android studio.
Bước 1: Add thư viện vào trong file gradle.
Mở file gradle và thêm dòng sau.
compile 'com.code-troopers.betterpickers:library:2.5.1'

*Trong trường hợp add thư viện vào bạn nhận được thông báo
Error:A problem occurred configuring project ':app'.
> Could not download library.aar (com.code-troopers.betterpickers:library:2.5.1)
   > Could not get resource 'https://jcenter.bintray.com/com/code-troopers/betterpickers/library/2.5.1/library-2.5.1.aar'.
      > Could not GET 'https://jcenter.bintray.com/com/code-troopers/betterpickers/library/2.5.1/library-2.5.1.aar'.
         > peer not authenticated

Lỗi trên có thể được khắc phục bằng cách thực hiện các bước sau:
  1. Download library-2.5.1.aar bằng trình cách paste vào trình duyệt địa chỉ https://jcenter.bintray.com/com/code-troopers/betterpickers/library/2.5.1/library-2.5.1.aar
  2. Copy file library-2.5.1.aar vào thư mục libs
  3. Thêm
    allprojects {
       repositories {
          jcenter()
          flatDir {
            dirs 'libs'
          }
       }
    }
    
    dependencies {
        compile(name:'library-2.5.1', ext:'aar')
    }
    

    vào file build gradle.
Bước 2: Bắt action và hiển thị Time/Date Picker vào main code.
Dưới đây là các ví dụ:
1. Calendar Date Picker.
button.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        CalendarDatePickerDialogFragment cdp = new CalendarDatePickerDialogFragment()
                .setOnDateSetListener(SampleCalendarDateBasicUsage.this)
                .setFirstDayOfWeek(Calendar.SUNDAY)
                .setPreselectedDate(towDaysAgo.getYear(), towDaysAgo.getMonthOfYear() - 1, towDaysAgo.getDayOfMonth())
                .setDateRange(minDate, null)
                .setThemeDark(true);
        cdp.show(getSupportFragmentManager(), FRAG_TAG_DATE_PICKER);
    }
});

2. Redial Time Picker
button.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        RadialTimePickerDialogFragment rtpd = new RadialTimePickerDialogFragment()
                .setOnTimeSetListener(SampleRadialTimeBasicUsage.this)
                .setStartTime(10, 10)
                .setThemeDark(true);
        rtpd.show(getSupportFragmentManager(), FRAG_TAG_TIME_PICKER);
    }
});
3. Recurrence Picker
button.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        FragmentManager fm = getSupportFragmentManager();
        Bundle bundle = new Bundle();
        Time time = new Time();
        time.setToNow();
        bundle.putLong(RecurrencePickerDialogFragment.BUNDLE_START_TIME_MILLIS, time.toMillis(false));
        bundle.putString(RecurrencePickerDialogFragment.BUNDLE_TIME_ZONE, time.timezone);
        bundle.putString(RecurrencePickerDialogFragment.BUNDLE_RRULE, mRrule);
        bundle.putBoolean(RecurrencePickerDialogFragment.BUNDLE_HIDE_SWITCH_BUTTON, true);

        RecurrencePickerDialogFragment rpd = new RecurrencePickerDialogFragment();
        rpd.setArguments(bundle);
        rpd.setOnRecurrenceSetListener(SampleRecurrenceBasicUsage.this);
        rpd.show(fm, FRAG_TAG_RECUR_PICKER);
    }
});
4. Timezone Picker
button.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        FragmentManager fm = getSupportFragmentManager();
        Bundle bundle = new Bundle();
        Time time = new Time();
        time.setToNow();
        bundle.putLong(TimeZonePickerDialogFragment.BUNDLE_START_TIME_MILLIS, time.toMillis(false));
        bundle.putString(TimeZonePickerDialogFragment.BUNDLE_TIME_ZONE, time.timezone);
        bundle.putString(RecurrencePickerDialogFragment.BUNDLE_RRULE, mRrule);

        TimeZonePickerDialogFragment tzpd = new TimeZonePickerDialogFragment();
        tzpd.setArguments(bundle);
        tzpd.setOnTimeZoneSetListener(SampleTimeZoneBasicUsage.this);
        tzpd.show(fm, FRAG_TAG_TIME_ZONE_PICKER);
    }
});
5. Date Picker
button.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        DatePickerBuilder dpb = new DatePickerBuilder()
                .setFragmentManager(getSupportFragmentManager())
                .setStyleResId(R.style.BetterPickersDialogFragment)
                .setYearOptional(true);
        dpb.show();
    }
});
6. Expiration Picker
button.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        ExpirationPickerBuilder epb = new ExpirationPickerBuilder()
                  .setFragmentManager(getSupportFragmentManager())
                  .setStyleResId(R.style.BetterPickersDialogFragment) 
                  .setMinYear(2000);
        epb.show();
    }
});
7. HMS Picker
button.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        HmsPickerBuilder hpb = new HmsPickerBuilder()
                .setFragmentManager(getSupportFragmentManager())
                .setStyleResId(R.style.BetterPickersDialogFragment);
        hpb.show();
    }
});
8. Number Picker
button.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        NumberPickerBuilder npb = new NumberPickerBuilder()
                .setFragmentManager(getSupportFragmentManager())
                .setStyleResId(R.style.BetterPickersDialogFragment)
                .setLabelText("LBS.");
        npb.show();
}
});
9. Time Picker
button.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        TimePickerBuilder tpb = new TimePickerBuilder()
                .setFragmentManager(getSupportFragmentManager())
                .setStyleResId(R.style.BetterPickersDialogFragment);
        tpb.show();
    }
});
Theming.
Đồng thời bạn có thể định nghĩa theme theo phong cách của riêng bạn.
    bpDialogBackground       :: drawable của DialogFragment background.
    bpTextColor              :: màu của text trong DialogFragment.
    bpDeleteIcon             :: drawable của delete button.
    bpCheckIcon              :: drawable của check button trong DateDialogPicker.
    bpKeyBackground          :: drawable của keyboard buttons.
    bpButtonBackground       :: drawable cho các nút Set, Cancel, and Delete buttons.
    bpDividerColor           :: màu của DialogFragment dividers.
    bpKeyboardIndicatorColor :: màu của ViewPagerIndicator trong DateDialogPicker.
  1. Tạo theme cá nhân trong file styles.xml
    <style name="MyCustomBetterPickerTheme">
        <item name="bpDialogBackground">@drawable/custom_dialog_background</item>
        <item name="bpTextColor">@color/custom_text_color</item>
        <item name="bpDeleteIcon">@drawable/ic_backspace_custom</item>
        <item name="bpCheckIcon">@drawable/ic_check_custom</item>
        <item name="bpKeyBackground">@drawable/key_background_custom</item>
        <item name="bpButtonBackground">@drawable/button_background_custom</item>
        <item name="bpDividerColor">@color/custom_divider_color</item>
        <item name="bpKeyboardIndicatorColor">@color/custom_keyboard_indicator_color</item>
    </style>
    
  2. Khởi tạo DialogFragment có sử dụng theme trên.
    DatePickerBuilder dpb = new DatePickerBuilder()
        .setFragmentManager(getSupportFragmentManager())
        .setStyleResId(R.style.MyCustomBetterPickerTheme);
    dpb.show();
    
Source code của chương trình được tải về tại đây.
Theo gitHub.com