NumberPicker是Android3.0以後引入的一個控件,NumberPicker 是用於選擇一組預約義好數字的控件。好比時間hour的選擇只有0—23有效,則能夠經過setMinValue和setMaxValue設定。java
使用該控件時需注意他的兩個listener和一個formatter:一個listener用於監聽當前value的變化;一個listener用於監聽該控件的scroll狀態;formatter用於格式化顯示該控件中的value。下面逐一介紹這幾個接口:android
一、NumberPicker.OnValueChangeListener :其函數public void onValueChange(NumberPicker picker, int oldVal, int newVal) ;oldVal前一個選中的值,newValue當前選中的值。算法
二、NumberPicker.OnScrollListener:其內部有三種scroll狀態SCROLL_STATE_FLING 、 SCROLL_STATE_IDLE 、 SCROLL_STATE_TOUCH_SCROLL。app
SCROLL_STATE_TOUCH_SCROLL:用戶按下去而後滑動。ide
SCROLL_STATE_FLING: 至關因而SCROLL_STATE_TOUCH_SCROLL的後續滑動操做。函數
SCROLL_STATE_IDLE: NumberPicker不在滾動。佈局
三、NumberPicker.Formatter: 格式化顯示數字,例如0—23格式化爲00 — 23 。具體的格式在format函數中規定,以下所示:this
public String format(int value) { String Str = String.valueOf(value); if (value < 10) { Str = "0" + Str; } return Str; }
value值在0—23之間,小於10的數在前面加上「0」。code
介紹完NumberPicker後,就要實現咱們今天的功能,首先先看效果圖,以下所示:orm
是否是很是漂亮那,這樣之後咱們的項目中須要這種效果,就直接就能夠拿來用了。要實現這種效果固然要先看咱們的佈局了,其實佈局裏面就三個NumberPicker以下所示:
就是這三個NumberPicker佈局出咱們剛纔的效果,佈局完成咱們就要找到這些控件,給他們加上監聽,來實現一些功能,這裏面是自定義FrameLayout在直接填充佈局作的。讓咱們來看看,以下所示:
package com.zqy.datetimepicker.datedialog; import java.util.Calendar; import com.zqy.datetimepicker.R; import android.content.Context; import android.text.format.DateFormat; import android.widget.FrameLayout; import android.widget.NumberPicker; import android.widget.NumberPicker.OnValueChangeListener; public class DateTimePicker extends FrameLayout { private final NumberPicker mDateSpinner; private final NumberPicker mHourSpinner; private final NumberPicker mMinuteSpinner; private Calendar mDate; private int mHour, mMinute; private String[] mDateDisplayValues = new String[7]; private OnDateTimeChangedListener mOnDateTimeChangedListener; public DateTimePicker(Context context) { super(context); /* *獲取系統時間 */ mDate = Calendar.getInstance(); mHour = mDate.get(Calendar.HOUR_OF_DAY); mMinute = mDate.get(Calendar.MINUTE); /** * 加載佈局 */ inflate(context, R.layout.datedialog, this); /** * 初始化控件 */ mDateSpinner = (NumberPicker) this.findViewById(R.id.np_date); mDateSpinner.setMinValue(0); mDateSpinner.setMaxValue(6); updateDateControl(); mDateSpinner.setOnValueChangedListener(mOnDateChangedListener); mHourSpinner = (NumberPicker) this.findViewById(R.id.np_hour); mHourSpinner.setMaxValue(23); mHourSpinner.setMinValue(0); mHourSpinner.setValue(mHour); mHourSpinner.setOnValueChangedListener(mOnHourChangedListener); mMinuteSpinner = (NumberPicker) this.findViewById(R.id.np_minute); mMinuteSpinner.setMaxValue(59); mMinuteSpinner.setMinValue(0); mMinuteSpinner.setValue(mMinute); mMinuteSpinner.setOnValueChangedListener(mOnMinuteChangedListener); } /** * * 控件監聽器 */ private NumberPicker.OnValueChangeListener mOnDateChangedListener = new OnValueChangeListener() { @Override public void onValueChange(NumberPicker picker, int oldVal, int newVal) { mDate.add(Calendar.DAY_OF_MONTH, newVal - oldVal); /** * 更新日期 */ updateDateControl(); /** * 給接口傳值 */ onDateTimeChanged(); } }; private NumberPicker.OnValueChangeListener mOnHourChangedListener = new OnValueChangeListener() { @Override public void onValueChange(NumberPicker picker, int oldVal, int newVal) { mHour = mHourSpinner.getValue(); onDateTimeChanged(); } }; private NumberPicker.OnValueChangeListener mOnMinuteChangedListener = new OnValueChangeListener() { @Override public void onValueChange(NumberPicker picker, int oldVal, int newVal) { mMinute = mMinuteSpinner.getValue(); onDateTimeChanged(); } }; private void updateDateControl() { /** * 星期幾算法 */ Calendar cal = Calendar.getInstance(); cal.setTimeInMillis(mDate.getTimeInMillis()); cal.add(Calendar.DAY_OF_YEAR, -7 / 2 - 1); mDateSpinner.setDisplayedValues(null); for (int i = 0; i < 7; ++i) { cal.add(Calendar.DAY_OF_YEAR, 1); mDateDisplayValues[i] = (String) DateFormat.format("MM.dd EEEE", cal); } mDateSpinner.setDisplayedValues(mDateDisplayValues); mDateSpinner.setValue(7 / 2); mDateSpinner.invalidate(); } /* *接口回調 參數是當前的View 年月日小時分鐘 */ public interface OnDateTimeChangedListener { void onDateTimeChanged(DateTimePicker view, int year, int month, int day, int hour, int minute); } /* *對外的公開方法 */ public void setOnDateTimeChangedListener(OnDateTimeChangedListener callback) { mOnDateTimeChangedListener = callback; } private void onDateTimeChanged() { if (mOnDateTimeChangedListener != null) { mOnDateTimeChangedListener.onDateTimeChanged(this,mDate.get(Calendar.YEAR), mDate.get(Calendar.MONTH), mDate.get(Calendar.DAY_OF_MONTH), mHour, mMinute); } } }
這段代碼就是找到這三個控件,分別給他們setMinValue(),setMaxValue(),也就是最大值和最小值,設置完成後,咱們給他們三個分別加上監聽setOnValueChangedListener下面有三個監聽方法,在mOnDateChangedListener這個方法了多了一個updateDateControl()方法,這個updateDateControl()方法裏面主要是月份和星期幾的關係算法,
寫完這些,值也拿到了,可是咱們須要把值傳出去,下面咱們又定義了一個接口來實現回調.接下來讓咱們在來看看對話框這個類,以下所示:
package com.zqy.datetimepicker.datedialog; import java.util.Calendar; import com.zqy.datetimepicker.datedialog.DateTimePicker.OnDateTimeChangedListener; import android.app.AlertDialog; import android.content.Context; import android.content.DialogInterface; import android.content.DialogInterface.OnClickListener; import android.text.format.DateUtils; public class DateTimePickerDialog extends AlertDialog implements OnClickListener { private DateTimePicker mDateTimePicker; private Calendar mDate = Calendar.getInstance(); private OnDateTimeSetListener mOnDateTimeSetListener; @SuppressWarnings("deprecation") public DateTimePickerDialog(Context context, long date) { super(context); mDateTimePicker = new DateTimePicker(context); setView(mDateTimePicker); /* *實現接口,實現裏面的方法 */ mDateTimePicker .setOnDateTimeChangedListener(new OnDateTimeChangedListener() { @Override public void onDateTimeChanged(DateTimePicker view, int year, int month, int day, int hour, int minute) { mDate.set(Calendar.YEAR, year); mDate.set(Calendar.MONTH, month); mDate.set(Calendar.DAY_OF_MONTH, day); mDate.set(Calendar.HOUR_OF_DAY, hour); mDate.set(Calendar.MINUTE, minute); mDate.set(Calendar.SECOND, 0); /** * 更新日期 */ updateTitle(mDate.getTimeInMillis()); } }); setButton("設置", this); setButton2("取消", (OnClickListener) null); mDate.setTimeInMillis(date); updateTitle(mDate.getTimeInMillis()); } /* *接口回調 *控件 秒數 */ public interface OnDateTimeSetListener { void OnDateTimeSet(AlertDialog dialog, long date); } /** * 更新對話框日期 * @param date */ private void updateTitle(long date) { int flag = DateUtils.FORMAT_SHOW_YEAR | DateUtils.FORMAT_SHOW_DATE | DateUtils.FORMAT_SHOW_WEEKDAY | DateUtils.FORMAT_SHOW_TIME; setTitle(DateUtils.formatDateTime(this.getContext(), date, flag)); } /* * 對外公開方法讓Activity實現 */ public void setOnDateTimeSetListener(OnDateTimeSetListener callBack) { mOnDateTimeSetListener = callBack; } public void onClick(DialogInterface arg0, int arg1) { if (mOnDateTimeSetListener != null) { mOnDateTimeSetListener.OnDateTimeSet(this, mDate.getTimeInMillis()); } } }
咱們一行一行看,首先咱們是繼承AlertDialog,在下面咱們new DateTimePicker,這個就是剛纔寫的類,咱們這個類的對象實現咱們剛纔寫的接口,把裏面的值取到,雖然取到了,可是咱們也不是在這裏顯示,因此咱們還須要定義接口,讓DateTimePickerDialog的對象去實現,下面就是咱們的寫的接口,咱們寫了那麼多,只爲MainActivity裏面的幾行代碼,讓咱們看看,以下所示:
package com.zqy.datetimepicker.activity; import java.text.SimpleDateFormat; import com.zqy.datetimepicker.R; import com.zqy.datetimepicker.datedialog.DateTimePickerDialog; import com.zqy.datetimepicker.datedialog.DateTimePickerDialog.OnDateTimeSetListener; import android.app.Activity; import android.app.AlertDialog; import android.os.Bundle; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; import android.widget.Toast; public class MainActivity extends Activity { private Button btn; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); btn = (Button) this.findViewById(R.id.button1); btn.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { showDialog(); } }); } public void showDialog() { DateTimePickerDialog dialog = new DateTimePickerDialog(this, System.currentTimeMillis()); /** * 實現接口 */ dialog.setOnDateTimeSetListener(new OnDateTimeSetListener() { public void OnDateTimeSet(AlertDialog dialog, long date) { Toast.makeText(MainActivity.this, "您輸入的日期是:" + getStringDate(date), Toast.LENGTH_LONG) .show(); } }); dialog.show(); } /** * 將長時間格式字符串轉換爲時間 yyyy-MM-dd HH:mm:ss * */ public static String getStringDate(Long date) { SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); String dateString = formatter.format(date); return dateString; } }
首先咱們仍是new DateTimePickerDialog這個類,咱們把系統時間傳過去,這樣時間對話框顯示的就是系統時間了,咱們用這個類的對象去實現咱們剛纔寫的接口,實現裏面的方法,咱們又定義了一個 將長時間格式字符串轉換爲時間 yyyy-MM-dd HH:mm:ss的方法,這樣我用一個Toast把接口裏面的值彈出來。OK,這樣咱們就實現完成了,有什麼不明白的能夠在下面留言。