Day 11 - DatePicker
สวัสดีครับ บทความนี้เป็นบทความที่ 11 แล้วนะครับ ที่ผมจะมาเขียน ในซีรีย์ Learn 30 Android Libraries in 30 days
สำหรับบทความทั้งหมด อ่านได้จากด้านล่างครับ
- Day 1 : AndroidStaggered Grid
- Day 2 : Paralloid
- Day 3 : Retrofit
- Day 4 : SwipeRefreshLayout
- Day 5 : Android GraphView
- Day 6 : Holo Color Picker
- Day 7 : Android Async Http
- Day 8 : Crashlytics
- Day 9 : Butter Knife
- Day 10 : Android Annotations
- Day 11 : DateTimePicker
- Day 12 : Circular Progress Button
- Day 13 : ViewPager
- Day 14 : ViewPagerIndicator
- Day 15 : FadingActionBar
- Day 16 : AutofitTextView
- Day 17 : SwipeListView
- Day 18 : ShowcaseView
- Day 19 : GreenDAO
- Day 20 : AndroidViewAnimation
- Day 21 : ActiveAndroid
- Day 22 : Twitter4J
- Day 23 : ListViewAnimations
- Day 24 : AndEngine
- Day 25 : EazeGraph
- Day 26 : Cardslib
- Day 27 : AdapterKit
- Day 28 : WeatherLib
- Day 29 : FlatUI
- Day 30 : Android Firebase
วันนี้ขอนำเสนอ DateTimePicker ครับ ต้องขอขอบคุณ คุณเอก ที่แนะนำมาครับ
DateTimePicker คืออะไร?
DatePicker ตัวนี้เป็นคนละตัวกับ DatePickerDialog ของทาง Android นะครับ ซึ่ง Library ตัวนี้จะเอาไว้ปรับแต่งให้หน้าตา DatePicker และ TimePicker ให้มีหน้าตาสวยงามขึ้นนะครับ ส่วนลักษณะการทำงาน วิธีการเรียกใช้ แทบเหมือนกันเลย
Installation
ขั้นตอนแรก ทำการติดตั้ง dependencies เปิดไฟล์ build.gradle
จากนั้นเพิ่มโค๊ดนี้ลงไป
dependencies {
compile 'com.github.flavienlaurent.datetimepicker:library:0.0.1'
}
กด Sync Gradle (ปัจจุบัน เวอร์ชัน 0.0.1)
Getting Started
ก่อนที่จะไปเริ่มสร้างโปรเจ็ค เรามารู้จักกับ DateTimePicker เบื้องต้นกันก่อนดีกว่า ตัว DateTimePicker จะมี Dialog อยู่ 2 แบบ นั่นก็คือ Dialog แบบ DatePicker และแบบ TimePicker
DatePicker
เป็น Dialog ที่เอาไว้เลือก วัน/เดือน/ปี เช่น วันเกิด วันปัจจุบัน เป็นต้น สำหรับการใช้งาน DatePicker เราจะใช้คลาส DatePickerDialog
วิธีการสร้าง ก็มีดังนี้
- ทำการสร้าง new instance ของ
DatePickerDialog
ขึ้นมา โดย set ค่า default ลงไป - ทำการ implement
DatePickerDialog.OnDateSetListener
เพื่อเอาไว้รับค่าเมื่อยูเซอร์กดเลือก วัน เสร็จแล้ว ก็จะส่ง callback กลับ
TimePicker
เหมือนกับ Dialog ด้านบน แต่ต่างกันที่ TimePicker จะเป็นการเลือก เวลา แทนที่จะเป็น วัน เดือน ปี การแสดง TimePicker เราจะใช้คลาส TimePickerDialog
วิธีสร้าง ก็มีดังนี้
- ทำการสร้าง new instance ของ
TimePickerDialog
ขึ้นมา - ทำการ implement interface
TimePickerDialog.OnTimeSetListener
เป็น Listener เพื่อเอาไว้รับค่า callback
Create new Project
เริ่มสร้างโปรเจ็ค ผมจะใช้ไฟล์ 2 ไฟล์เช่นเคย คือ DateTimePickerActivity
และ activity_datetime_picker.xml
ในส่วนของเลเอาท์ จะมี Button สำหรับกดเลือก DatePicker และ TimePicker ขึ้นมาแสดง เมื่อเลือกแล้ว ก็จะแสดง วันที่/เวลาที่เลือก ลงบน TextView ที่กำหนดไว้ เพราะฉะนั้นเลเอาท์ จะได้ประมาณนี้
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="16dp">
<RelativeLayout android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true">
<TextView android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:textSize="24sp"
android:textColor="#ff0071ff"
android:id="@+id/text_date"
android:layout_alignParentTop="true"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"/>
<Button
android:id="@+id/button_date"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/select_date"
android:layout_below="@+id/text_date"
android:layout_centerHorizontal="true"/>
<TextView android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="24sp"
android:textColor="#ffee1789"
android:id="@+id/text_time"
android:layout_marginTop="64dp"
android:gravity="center"
android:layout_below="@+id/button_date"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"/>
<Button
android:id="@+id/button_time"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/select_time"
android:layout_toEndOf="@+id/text_time"
android:layout_below="@+id/text_time"
android:layout_alignLeft="@+id/button_date"
android:layout_alignStart="@+id/button_date"/>
</RelativeLayout>
</RelativeLayout>
ต่อมาที่ไฟล์ DateTimePicker.java
ผมสร้างมันขึ้นมา แล้วทำการ binding View ต่างๆ แบบนี้ ส่วน Calendar เอาไว้สำหรับแสดงเวลาปัจจุบันครับ
package com.devahoy.learn30androidlibraries.day11;
import android.os.Bundle;
import android.support.v7.app.ActionBarActivity;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import com.devahoy.learn30androidlibraries.R;
import com.fourmob.datetimepicker.date.DatePickerDialog;
import com.sleepbot.datetimepicker.time.RadialPickerLayout;
import com.sleepbot.datetimepicker.time.TimePickerDialog;
import java.text.DateFormat;
import java.util.Calendar;
import java.util.Date;
public class DateTimePickerActivity extends ActionBarActivity {
private DatePickerDialog mDatePicker;
private TimePickerDialog mTimePicker;
private Calendar mCalendar;
private Button mTimeButton;
private Button mDateButton;
private TextView mTextTime;
private TextView mTextDate;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.day11_activity_date_picker);
mTimeButton = (Button) findViewById(R.id.button_time);
mDateButton = (Button) findViewById(R.id.button_date);
mTextTime = (TextView) findViewById(R.id.text_time);
mTextDate = (TextView) findViewById(R.id.text_date);
mCalendar = Calendar.getInstance();
}
}
สังเกตว่า ต้อง import ให้ถูกด้วยนะครับ คนละตัวกับ default ของ android ที่ถูกต้องเป็น
import com.fourmob.datetimepicker.date.DatePickerDialog;
import com.sleepbot.datetimepicker.time.TimePickerDialog;
ต่อมาผมทำการสร้าง DatePickerDialog ขึ้นมา โดยกำหนดค่าเริ่มต้นให้กับ Dialog ว่าจะเซทเป็นวันที่เท่าไหร่ ตามนี้
mDatePicker = DatePickerDialog.newInstance(onDateSetListener,
mCalendar.get(Calendar.YEAR), // ปี
mCalendar.get(Calendar.MONTH), // เดือน
mCalendar.get(Calendar.DAY_OF_MONTH),// วัน (1-31)
false); // ให้สั่นหรือไม่?
ต่อมาสร้าง TimePickerDialog ขึ้นมา และกำหนดค่าเริ่มต้นให้มันดังนี้ โดยกำหนดเวลาเป็น 10.30 น. ในระบบ 24-Hr
mTimePicker = TimePickerDialog.newInstance(onTimeSetListener,
10, // หน่วยเข็มชั่วโมง
30, // เข็มนาที
true, // ใช้ระบบนับแบบ 24-Hr หรือไม่? (0 - 23 นาฬิกา)
false); // ให้สั่นหรือไม่?
หากคุณตั้งค่า vibrate ้ต้องไปทำการตั้ง permission ที่ไฟล์ AndroidManifest.xml
ด้วยนะครับ
<uses-permission android:name="android.permission.VIBRATE" />
จะเห็นได้ว่า ทั้งสองด้านบนที่ผมสร้างมี error? เนื่องจากว่า onDateSetListener
กับ onTimeSetListener
มันคืออะไร?
มันคือ Listener ที่จะเอาไว้รับค่าสำหรับส่ง Listener กลับมา ทำได้ โดยการให้ Activity ทำการ implement แล้วก็ override เมธอด onDateSet()
และ onTimeSet()
หรืออีกวิธีนึง ก็สร้าง Interface ขึ้นมาใหม่ก็ได้ ในที่นี้ผมใช้วิธีสร้าง Interface ขึ้นมาใหม่ ดังนี้
private TimePickerDialog.OnTimeSetListener onTimeSetListener =
new TimePickerDialog.OnTimeSetListener() {
@Override
public void onTimeSet(RadialPickerLayout radialPickerLayout, int hourOfDay, int minute) {
mTextTime.setText(" " + hourOfDay + " : " + minute);
}
};
private DatePickerDialog.OnDateSetListener onDateSetListener =
new DatePickerDialog.OnDateSetListener() {
@Override
public void onDateSet(DatePickerDialog datePickerDialog, int year, int month, int day) {
DateFormat dateFormat = DateFormat.getDateInstance(DateFormat.LONG);
mCalendar.set(year, month, day);
Date date = mCalendar.getTime();
String textDate = dateFormat.format(date);
mTextDate.setText(textDate);
}
};
ด้านบนไม่มีอะไรมาก เพียงแค่ เมื่อผู้ใช้กดเลือกแล้ว ก็จะ set ค่าไปที่ TextView ครับ ส่วน DatePickerDialog มีการใช้ DateFormat มาช่วยในการจัดฟอแมตเฉยๆครับ
เมื่อเราทำ Dialog เสร็จแล้ว ขั้นตอนต่อไป ก็สั่งให้มันโชว์ เมื่อมีการกดปุ่ม ฉะนั้น ก็เพิ่ม setOnClickListener
ให้กับปุ่มทั้งสองดังนี้
mTimeButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
mTimePicker.show(getSupportFragmentManager(), "timePicker");
}
});
mDateButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
mDatePicker.setYearRange(2000, 2020);
mDatePicker.show(getSupportFragmentManager(), "datePicker");
}
});
โดยด้านบน TimePickerDialog ทำการโชว์ โดยรับ parameter เป็น Fragment และ String (ตั้งชื่ออะไรก็ได้ เอาไว้ใช้ระบุตัว เวลา implement พวก Fragment Transaction หากไม่ได้ใช้ ก็ใส่ไรไปก็ได้ครับ)
ส่วน DatePickerDialog ทำการเสร็จ range ของปี ว่าจะให้เลือกได้ระหว่างปีอะไรถึงปีอะไร ต่อมาก็สั่งโชว์เหมือนกันเลย
สุดท้าย ทดสอบรันโปรแกรม จะได้หน้าตาแบบนี้
ลองเล่นกันดูนะครับ
สรุป
หลังจากที่ลองเล่นแล้วรู้สึกว่า มันแทบจะเหมือนกับ Picker ที่เป็น Default ของ Android เลย ต่างกันที่หน้าตา ดีไซน์เท่านั้นครับ สำหรับใครที่อยากเปลี่ยนหน้าตา Dialog ให้ดูสวยงาม ก็แนะนำ ลองเอาอันนี้ไปเล่นกันดูนะครับ :D
- Authors
- Name
- Chai Phonbopit
- Website
- @Phonbopit