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"?>                                        
就是这三个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,这样我们就实现完成了,有什么不明白的可以在下面留言。


源码下载,请点击这里







更多相关文章

  1. Android:(12)显示控件使用
  2. Serializable和Parcelable的解析与使用
  3. Android(安卓)的网络编程(3)-HttpURLConnection接口
  4. Android字符串资源文件format方法使用实例
  5. Android应用程序换肤实现系列(二)
  6. OpenMax多媒体引擎
  7. android fragmnet重叠问题解决方案
  8. Android四大核心组件之一-----Service(服务)的基本知识
  9. 旋屏时,OnCreate方法重复调用的解决

随机推荐

  1. android菜单详解六:快捷键和菜单intent
  2. Android——横竖屏切换以及数据保存
  3. Android(安卓)matrix偏移(平移),旋转,缩放,
  4. androidjunit test基本知识(一)
  5. Android(安卓)自定义 View 理论基础
  6. Eclipse中编译Android工程时出现的问题解
  7. android面试题总结—摘自csdn
  8. android stdio3.6中textcolor颜色代码大
  9. 最全面总结 Android(安卓)WebView与 JS
  10. 【Android开发】布局管理器-表格布局