使用NumberPicker定制自己喜欢的Date&TimePicker

1.NumberPicker简介:

  NumberPicker是Android3.0之后引入的一个控件,主要功能是用于选择一组预定义好数字的控件。

  该控件主要需要指导一个用于监听当前value变化的listener、一个用于监听该控件scroll状态的listener和一个用于格式化显示该控件中value的formatter:

    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 。

2.使用NumberPicker定制Date&TimePicker:

  1) 创建布局样式

 1 <?xml version="1.0" encoding="utf-8"?>
 2 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
 3     android:layout_width="fill_parent"
 4     android:layout_height="fill_parent"
 5     android:gravity="center"
 6     android:orientation="vertical">
 7 
 8     <LinearLayout
 9         android:layout_width="match_parent"
10         android:layout_height="wrap_content"
11         android:gravity="center_horizontal"
12         android:orientation="horizontal"
13         android:paddingRight="10dp">
14 
15         <NumberPicker
16             android:id="@+id/date_year_picker"
17             android:layout_width="0dp"
18             android:layout_height="wrap_content"
19             android:layout_marginLeft="10dp"
20             android:layout_weight="1" />
21 
22         <NumberPicker
23             android:id="@+id/date_mouth_picker"
24             android:layout_width="0dp"
25             android:layout_height="wrap_content"
26             android:layout_marginLeft="10dp"
27             android:layout_weight="1" />
28 
29         <NumberPicker
30             android:id="@+id/date_day_picker"
31             android:layout_width="0dp"
32             android:layout_height="wrap_content"
33             android:layout_marginLeft="10dp"
34             android:layout_weight="1" />
35     </LinearLayout>
36 </LinearLayout>
View Code

  2) 继承FrameLayout实现填充布局

  1 package com.snd.picker;
  2 
  3 import android.content.Context;
  4 import android.util.Log;
  5 import android.widget.FrameLayout;
  6 import android.widget.NumberPicker;
  7 
  8 import java.util.Calendar;
  9 
 10 /**
 11  * Created by Hebo-KA-0045 on 2016/10/9.
 12  */
 13 
 14 public class DatePicker extends FrameLayout {
 15 
 16     private int mYear, mMonth, mDay;// 当前年月日
 17     private String[] mDateDisplayValues = new String[7];
 18     private Calendar mDate;
 19 
 20     private NumberPicker mDateYearPicker, mDateMonthPicker, mDateDayPicker;
 21 
 22     private OnDateChangedListener mOnDateChangedListener;
 23 
 24     public DatePicker(Context context) {
 25         super(context);
 26         mDate = Calendar.getInstance();
 27         mYear = mDate.get(Calendar.YEAR);
 28         mMonth = mDate.get(Calendar.MONTH);
 29         mDay = mDate.get(Calendar.DAY_OF_MONTH);
 30 
 31         init(context);// 加载布局文件,并初始化相应控件
 32     }
 33 
 34     /**
 35      * 加载布局,并初始化控件
 36      *
 37      * @param context
 38      */
 39     private void init(Context context) {
 40         inflate(context, R.layout.date_picker_dialog, this);// 加载布局
 41 
 42         /**
 43          * 初始化控件
 44          */
 45         mDateYearPicker = (NumberPicker) this.findViewById(R.id.date_year_picker);
 46         mDateYearPicker.setMinValue(1900);
 47         mDateYearPicker.setMaxValue(2100);
 48         mDateYearPicker.setValue(mYear);
 49         mDateMonthPicker = (NumberPicker) this.findViewById(R.id.date_mouth_picker);
 50         mDateMonthPicker.setMinValue(1);
 51         mDateMonthPicker.setMaxValue(12);
 52         mDateMonthPicker.setValue(mMonth + 1);
 53         mDateDayPicker = (NumberPicker) this.findViewById(R.id.date_day_picker);
 54         mDateDayPicker.setMinValue(1);
 55         mDateDayPicker.setMaxValue(getDaysInMonthAndYear(mYear, mMonth - 1));
 56         mDateDayPicker.setValue(mDay);
 57 
 58         initListener(context);
 59     }
 60 
 61     /**
 62      * 初始化监听器
 63      */
 64     private void initListener(final Context context) {
 65         mDateYearPicker.setOnValueChangedListener(new NumberPicker.OnValueChangeListener() {
 66             @Override
 67             public void onValueChange(NumberPicker picker, int oldVal, int newVal) {
 68                 mDate.add(Calendar.YEAR, newVal - oldVal);
 69                 mYear = mDateYearPicker.getValue();
 70                 mDateDayPicker.setMaxValue(getDaysInMonthAndYear(mYear, mMonth));
 71                 if (mYear == 1900 || mYear == 2100) {
 72                     mDateYearPicker.setWrapSelectorWheel(false);
 73                 } else if (mYear > Calendar.YEAR) {
 74                 }
 75                 onDateChanged();
 76             }
 77         });
 78         mDateMonthPicker.setOnValueChangedListener(new NumberPicker.OnValueChangeListener() {
 79             @Override
 80             public void onValueChange(NumberPicker picker, int oldVal, int newVal) {
 81                 mDate.add(Calendar.MONTH, newVal - oldVal);
 82                 mMonth = mDateMonthPicker.getValue();
 83                 mDateDayPicker.setMaxValue(getDaysInMonthAndYear(mYear, mMonth));
 84                 onDateChanged();
 85             }
 86         });
 87         mDateDayPicker.setOnValueChangedListener(new NumberPicker.OnValueChangeListener() {
 88             @Override
 89             public void onValueChange(NumberPicker picker, int oldVal, int newVal) {
 90                 mDate.add(Calendar.DAY_OF_MONTH, newVal - oldVal);
 91                 mMonth = mDateMonthPicker.getValue();
 92                 mDay = mDateDayPicker.getValue();
 93                 onDateChanged();
 94             }
 95         });
 96     }
 97 
 98     /**
 99      * 获取某一年某一月的天数
100      *
101      * @param year
102      * @param month 取值范围1-12
103      * @return
104      */
105     private int getDaysInMonthAndYear(int year, int month) {
106         Calendar calendar = Calendar.getInstance();
107         calendar.set(Calendar.YEAR, year);
108         calendar.set(Calendar.MONTH, month - 1);
109         return calendar.getActualMaximum(Calendar.DATE);
110 
111     }
112 
113     private void onDateChanged() {
114         if (mOnDateChangedListener != null) {
115             mOnDateChangedListener.onDateChanged(this, mYear, mMonth, mDay);
116         }
117     }
118 
119     /*
120      *对外的公开方法
121      */
122     public void setOnDateTimeChangedListener(OnDateChangedListener listener) {
123         mOnDateChangedListener = listener;
124     }
125 
126     public interface OnDateChangedListener {
127         void onDateChanged(DatePicker view, int year, int month, int day);
128     }
129 }
View Code

  3) 实现自定义Dialog

 1 package com.snd.picker;
 2 
 3 import android.app.AlertDialog;
 4 import android.content.Context;
 5 import android.content.DialogInterface;
 6 import android.text.format.DateUtils;
 7 
 8 import java.util.Calendar;
 9 
10 /**
11  * Created by Hebo-KA-0045 on 2016/10/9.
12  */
13 public class DatePickerDialog extends AlertDialog implements DialogInterface.OnClickListener {
14 
15     private DatePicker mDatePicker;
16     private Calendar mDate;
17 
18     private OnDateSetListener mOnDateSetListener;
19 
20     @Override
21     public void onClick(DialogInterface dialog, int which) {
22         if (mOnDateSetListener != null) {
23             mOnDateSetListener.OnDateSet(this, mDate.getTimeInMillis());
24         }
25     }
26 
27     public DatePickerDialog(Context context, long date) {
28         super(context);
29         mDate = Calendar.getInstance();
30         mDatePicker = new DatePicker(context);
31         setView(mDatePicker);
32         mDatePicker.setOnDateTimeChangedListener(new DatePicker.OnDateChangedListener() {
33             @Override
34             public void onDateChanged(DatePicker view, int year, int month, int day) {
35                 mDate.set(Calendar.YEAR, year);
36                 mDate.set(Calendar.MONTH, month - 1);
37                 mDate.set(Calendar.DAY_OF_MONTH, day);
38 
39                 updateTitle(mDate.getTimeInMillis());
40             }
41         });
42 
43         setButton("确定", this);
44         mDate.setTimeInMillis(date);
45         updateTitle(mDate.getTimeInMillis());
46     }
47 
48     private void updateTitle(long date) {
49         int flag = DateUtils.FORMAT_SHOW_YEAR | DateUtils.FORMAT_SHOW_DATE;
50         setTitle(DateUtils.formatDateTime(this.getContext(), date, flag));
51     }
52 
53     /*
54      * 对外公开方法让Activity实现
55      */
56     public void setOnDateSetListener(OnDateSetListener listener) {
57         mOnDateSetListener = listener;
58     }
59 
60     /**
61      * 接口回调
62      * 控件 秒数
63      */
64     public interface OnDateSetListener {
65         void OnDateSet(AlertDialog dialog, long date);
66     }
67 }
View Code

  4) 使用

 1 package com.snd.picker;
 2 
 3 import android.app.Activity;
 4 import android.app.AlertDialog;
 5 import android.os.Bundle;
 6 import android.view.View;
 7 import android.widget.Toast;
 8 
 9 import java.text.SimpleDateFormat;
10 
11 public class MainActivity extends Activity {
12 
13     @Override
14     protected void onCreate(Bundle savedInstanceState) {
15         super.onCreate(savedInstanceState);
16         setContentView(R.layout.main_acty);
17 
18         findViewById(R.id.btn).setOnClickListener(new View.OnClickListener() {
19             @Override
20             public void onClick(View v) {
21                 DatePickerDialog dialog = new DatePickerDialog(MainActivity.this,
22                         System.currentTimeMillis());
23                 /**
24                  * 实现接口
25                  */
26                 dialog.setOnDateSetListener(new DatePickerDialog.OnDateSetListener() {
27                     @Override
28                     public void OnDateSet(AlertDialog dialog, long date) {
29                         Toast.makeText(MainActivity.this,
30                                 "您输入的日期是:" + getStringDate(date), Toast.LENGTH_LONG)
31                                 .show();
32                     }
33                 });
34                 dialog.show();
35             }
36         });
37     }
38 
39     /**
40      * 将长时间格式字符串转换为时间 yyyy-MM-dd HH:mm:ss
41      */
42     public static String getStringDate(Long date) {
43         SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
44         String dateString = formatter.format(date);
45         return dateString;
46     }
47 }
View Code
但行好事,莫问前程;你若盛开,蝴蝶自来;你若坚强,命运自会给你打赏。
原文地址:https://www.cnblogs.com/songjie-xuan/p/5942669.html