关于日期和时间的几个相关控件,包括DatePicker(日期选择控件)、TimePicker(时间选择控件)、DatePickerDialog(日期选择对话框)、TimePickerDialog(时间选择对话框)、AnalogClock(模拟时钟控件)、DigitalClock(数字时钟控件)。
DatePicker 、 TimePicker 都继承自android.widget.FrameLayout,并且默认展示风格、与操作风格也类似。DatePicker用于展示一个日期选择控件,TimePicker用于展示一个时间选择控件。
作为一个日期选择控件,DatePicker可以通过设置属性来确定日期选择范围,也可以通过定义好的方法获取到当前选中的时间,并且在修改日期的时候,有响应的事件对其进行响应。
DatePicker常用相关属性:
- android:calendarViewShown:是否显示日历。
- android:startYear:设置可选开始年份。
- android:endYear:设置可选结束年份。
- android:maxDate:设置可选最大日期,以mm/dd/yyyy格式设置。
- android:minDate:设置可选最小日期,以mm/dd/yyyy格式设置。
DatePicker的方法而言,除了常用获取属性的setter、getter方法之外,还需要特别注意一个初始化的方法init()方法,用于做DatePicker控件的初始化,并且设置日期被修改后,回调的响应事件。此方法的签名如下:
init(int year, int monthOfYear, int dayOfMonth, DatePicker.OnDateChangedListener onDateChangedListener)
从上面的init()方法可以看到,DatePicker被修改时响应的事件是DatePicker.OnDateChangedListener 事件,如果要响应此事件,需要实现其中的onDateChanged()方法,其中参数从签名即可了解意思,这里不再累述。
onDateChanged(DatePicker view, int year, int monthOfYear, int dayOfMonth)
作为一个时间选择控件来说,TimePicker需要与时间相关的getter、setter方法之外,还需要有时间被修改够,回调的响应事件。
TimePicker常用方法有如下几个:
- is24HourView():判断是否为24小时制。
- setIs24HourView():设置是否为24小时制显示。
- getCurrentXxx():获取当前时间。
- setCurrentXxx():设置当前时间。
- setOnTimeChangedListener():设置时间被修改的回调方法。
TimePicker控件被修改的回调方法,通过setOnTimeChangedListener()方法设置,其传递一个 TimePicker.OnTimeChangedListener 接口,需要实现其中的onTimeChanged()方法。
问题1:其实现思路就是自定义一个Dialog,然后往里面同时放入DatePicker和TimePicker,直接贴代码:
date_time_picker.xml:
1. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
2. xmlns:tools="http://schemas.android.com/tools"
3. android:layout_width="wrap_content"
4. android:layout_height="wrap_content"
5. android:gravity="center"
6. android:orientation="horizontal" >
7.
8. <DatePicker
9. android:id="@+id/new_act_date_picker"
10. android:layout_width="0dip"
11. android:layout_height="wrap_content"
12. android:layout_weight="0.6"
13. android:calendarViewShown="false" />
14.
15. <TimePicker
16. android:id="@+id/new_act_time_picker"
17. android:layout_width="0dip"
18. android:layout_height="wrap_content"
19. android:layout_weight="0.3"/> -->
20.
21. <DatePicker
22. android:id="@+id/new_act_date_picker"
23. android:layout_width="wrap_content"
24. android:layout_height="wrap_content"
25. android:calendarViewShown="false" />
26.
27. <TimePicker
28. android:id="@+id/new_act_time_picker"
29. android:layout_width="wrap_content"
30. android:layout_height="wrap_content"/>
31.
32. </LinearLayout>
然后在需要显示日期时间选择器的地方(一般是一个onClickListener中)实例化dialog:
DemoActivity.java
1. arriveAtBtn.setOnClickListener(new
2. @SuppressLint("NewApi")
3. @Override
4. public void
5. null);
6. final
7. final
8.
9. // Init DatePicker
10. int
11. int
12. int
13. if
14. // Use the current date as the default date in the picker
15. final
16. year = c.get(Calendar.YEAR);
17. month = c.get(Calendar.MONTH);
18. day = c.get(Calendar.DAY_OF_MONTH);
19. else
20. year = NewActActivity.arrive_year;
21. month = NewActActivity.arrive_month;
22. day = NewActActivity.arrive_day;
23. }
24. null);
25.
26. // Init TimePicker
27. int
28. int
29. if
30. // Use the current time as the default values for the picker
31. final
32. hour = c.get(Calendar.HOUR_OF_DAY);
33. minute = c.get(Calendar.MINUTE);
34. else
35. hour = NewActActivity.arrive_hour;
36. minute = NewActActivity.arrive_min;
37. }
38. true);
39. timePicker.setCurrentHour(hour);
40. timePicker.setCurrentMinute(minute);
41.
42. // Build DateTimeDialog
43. new AlertDialog.Builder(NewActActivity.this);
44. builder.setView(view);
45. builder.setTitle(R.string.new_act_date_time_picker_title);
46. new
47. @Override
48. public void onClick(DialogInterface dialog, int
49. arrive_year = datePicker.getYear();
50. arrive_month = datePicker.getMonth();
51. arrive_day = datePicker.getDayOfMonth();
52. String dateStr = DateUtil.formatDate(arrive_year, arrive_month, arrive_day);
53. arriveDateBtn.setText(dateStr);
54.
55. arrive_hour = timePicker.getCurrentHour();
56. arrive_min = timePicker.getCurrentMinute();
57. String timeStr = DateUtil.formatTime(arrive_hour, arrive_min);
58. arriveTimeBtn.setText(timeStr);
59. }
60. });
61. builder.show();
62. }
63. });
这样就可以实现日期时间选择器了,这里就有点layout上的小问题,你是需要datepicker和timepicker水平排列还是竖直排列,竖直排列是没问题的:下面给出两个数值排列的效果图:
(1)DatePicker控件中设置android:calendarViewShown="false" 时的效果图:
(2)(1)DatePicker控件中设置android:spinnersShown="false" 时的效果图:
当然,如果你android:calendarViewShown和android:spinnersShown都不设置为false的话,会同时显示日历和滚动条样式,我想一般不会有人想要这样的视图吧。
水平排列是有问题的,那就是屏幕太挤,两个控件显示不全,看看效果图:
可是有人就是有水平排列的需求怎么办?这就是本文要讲的第二个问题:改变datepicker和timepicker的宽度。
网上找了很久,没有发现很有效的方法,说是这两个控件的子元素的宽度是不能自定义的,实际上把控件的所有属性看了一遍,也确实没有发现相关的属性;有人是通过自定义DatePicker和TimePicker来实现的,找了个demo,确实是实现了,不过已经相当于是自己写了一个插件了,我嫌麻烦,加之稳定性方面的考虑,没有去用,不过我会在最后把这个demo的src带上,有需要的人可以自己下载来研究。难道真不能改宽度吗?突然想到我是不是能从代码中的datePicker对象一步步往下找到其child,直接改child的宽度呢,于是debug,果然通过这种方式成功改变了宽度值,代码如下,只要在DemoActivity.java中增加一块专门用于实现改宽度的代码就行:
DemoActivity.java:
1. arriveAtBtn.setOnClickListener(new
2. @SuppressLint("NewApi")
3. @Override
4. public void
5. null);
6. final
7. final
8.
9. // Change DatePicker layout
10. 0) ; // LinearLayout
11. 0); // 0 : LinearLayout; 1 : CalendarView
12. for(int i = 0; i < dpSpinner.getChildCount(); i ++) {
13. // 0-2 : NumberPicker
14. new LayoutParams(120, LayoutParams.WRAP_CONTENT);
15. 0;
16. 30;
17. numPicker.setLayoutParams(params1);
18.
19. // EditText cusET = (EditText)numPicker.getChildAt(0); // CustomEditText
20. // cusET.setTextSize(14);
21. // cusET.setWidth(70);
22. }
23.
24. // Change TimePicker layout
25. 0) ; // LinearLayout
26. 0); // 0 : LinearLayout; 1 : CalendarView
27. for(int i = 0; i < tpSpinner.getChildCount(); i ++) {
28. // child(1) is a TextView ( : )
29. if (i == 1) {
30. continue;
31. }
32. // 0 : NumberPicker; 1 : TextView; 2 : NumberPicker
33. new LayoutParams(100, LayoutParams.WRAP_CONTENT);
34. 0;
35. 30;
36. numPicker.setLayoutParams(params3);
37.
38. // EditText cusET = (EditText)numPicker.getChildAt(0); // CustomEditText
39. // cusET.setTextSize(14);
40. // cusET.setWidth(70);
41. }
42.
43. // Init DatePicker
44. int
45. int
46. int
47. if
48. // Use the current date as the default date in the picker
49. final
50. year = c.get(Calendar.YEAR);
51. month = c.get(Calendar.MONTH);
52. day = c.get(Calendar.DAY_OF_MONTH);
53. else
54. year = NewActActivity.arrive_year;
55. month = NewActActivity.arrive_month;
56. day = NewActActivity.arrive_day;
57. }
58. null);
59.
60. // Init TimePicker
61. int
62. int
63. if
64. // Use the current time as the default values for the picker
65. final
66. hour = c.get(Calendar.HOUR_OF_DAY);
67. minute = c.get(Calendar.MINUTE);
68. else
69. hour = NewActActivity.arrive_hour;
70. minute = NewActActivity.arrive_min;
71. }
72. true);
73. timePicker.setCurrentHour(hour);
74. timePicker.setCurrentMinute(minute);
75.
76. // Build DateTimeDialog
77. new AlertDialog.Builder(NewActActivity.this);
78. builder.setView(view);
79. builder.setTitle(R.string.new_act_date_time_picker_title);
80. new
81. @Override
82. public void onClick(DialogInterface dialog, int
83. arrive_year = datePicker.getYear();
84. arrive_month = datePicker.getMonth();
85. arrive_day = datePicker.getDayOfMonth();
86. String dateStr = DateUtil.formatDate(arrive_year, arrive_month, arrive_day);
87. arriveDateBtn.setText(dateStr);
88.
89. arrive_hour = timePicker.getCurrentHour();
90. arrive_min = timePicker.getCurrentMinute();
91. String timeStr = DateUtil.formatTime(arrive_hour, arrive_min);
92. arriveTimeBtn.setText(timeStr);
93. }
94. });
95. builder.show();
96. }
97. });
通过这种方式实现的效果图如下:
其实这种方法也有问题:我的手机是1080P(5.5寸)的屏,显示效果是这样,如果屏幕小点,分辨率更低的屏呢,很可能屏幕宽度不够显示,当然你可以修改一下上面代码的逻辑,根据屏幕大小来动态设置控件的宽度值,而不是设成定值,具体的这些细节按自己的需求来做吧,我这里只是想记录一下自己发现的这种改变datepicker和timepicker宽度的方法,至于是否实用,我不负责,我只当是学习一下android。不过我的项目里最终没有用这个方案,最终选择了垂直排列的日历格式那个方案。
http://android.blog.51cto.com/268543/333769