標籤:android時間對話方塊 時間對話方塊 numberpicker android numberpicker
NumberPicker是Android3.0之後引入的一個控制項,NumberPicker 是用於選擇一組預定義好數位控制項。比如時間hour的選擇只有0—23有效,則可以通過setMinValue和setMaxValue設定。
使用該控制項時需注意他的兩個listener和一個formatter:一個listener用於監聽當前value的變化;一個listener用於監聽該控制項的scroll狀態;formatter用於格式化顯示該控制項中的value。下面逐一介紹這幾個介面:
1、NumberPicker.OnValueChangeListener :其函數public void onValueChange(NumberPicker picker, int oldVal, int newVal) ;oldVal前一個選中的值,newValue當前選中的值。
2、NumberPicker.OnScrollListener:其內部有三種scroll狀態SCROLL_STATE_FLING 、 SCROLL_STATE_IDLE 、 SCROLL_STATE_TOUCH_SCROLL。
SCROLL_STATE_TOUCH_SCROLL:使用者按下去然後滑動。
SCROLL_STATE_FLING: 相當於是SCROLL_STATE_TOUCH_SCROLL的後續滑動操作。
SCROLL_STATE_IDLE: NumberPicker不在滾動。
3、NumberPicker.Formatter: 格式化顯示數字,例如0—23格式化為00 — 23 。具體的格式在format函數中規定,如下所示:
public String format(int value) { String Str = String.valueOf(value); if (value < 10) { Str = "0" + Str; } return Str; } value值在0—23之間,小於10的數在前面加上“0”。
介紹完NumberPicker後,就要實現我們今天的功能,首先先看,如下所示:
是不是非常漂亮那,這樣以後我們的項目中需要這種效果,就直接就可以拿來用了。要實現這種效果當然要先看我們的布局了,其實布局裡面就三個NumberPicker如下所示:
<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" android:gravity="center" android:orientation="vertical" > <LinearLayout android:layout_width="wrap_content" android:layout_height="wrap_content" android:gravity="center_horizontal" android:orientation="horizontal" android:paddingLeft="3.0dip" > <NumberPicker android:id="@+id/np_date" android:layout_width="120.0dip" android:layout_height="wrap_content" android:button="@null" /> <NumberPicker android:id="@+id/np_hour" android:layout_width="50.0dip" android:layout_height="wrap_content" android:layout_marginLeft="5.0dip" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" android:text=":" android:textSize="20.0sp" /> <NumberPicker android:id="@+id/np_minute" android:layout_width="50.0dip" android:layout_height="wrap_content" /> </LinearLayout></LinearLayout>
就是這三個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() {@Overridepublic void onValueChange(NumberPicker picker, int oldVal, int newVal) {mDate.add(Calendar.DAY_OF_MONTH, newVal - oldVal);/** * 更新日期 */updateDateControl();/** * 給介面傳值 */onDateTimeChanged();}};private NumberPicker.OnValueChangeListener mOnHourChangedListener = new OnValueChangeListener() {@Overridepublic void onValueChange(NumberPicker picker, int oldVal, int newVal) {mHour = mHourSpinner.getValue();onDateTimeChanged();}};private NumberPicker.OnValueChangeListener mOnMinuteChangedListener = new OnValueChangeListener() {@Overridepublic 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 implementsOnClickListener {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() {@Overridepublic 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;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.main);btn = (Button) this.findViewById(R.id.button1);btn.setOnClickListener(new OnClickListener() {@Overridepublic 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,這樣我們就實現完成了,有什麼不明白的可以在下面留言。
源碼下載,請點擊這裡