Android日期對話框NumberPicker的用法教程

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,這樣咱們就實現完成了,有什麼不明白的能夠在下面留言。

相關文章
相關標籤/搜索