效果如下:

调用的代码:

  1. @OnClick(R.id.btn0)
  2. public void btn0() {
  3. final AlertDialog dialog = new AlertDialog.Builder(context).create();
  4. dialog.show();
  5. Window window = dialog.getWindow();
  6. window.setContentView(R.layout.dialog_change_date);
  7. window.setBackgroundDrawable(new ColorDrawable(0x00000000)); // 处理5.0以上对话框的白边问题
  8. window.setGravity(Gravity.BOTTOM);
  9. final DatePickerView datePickerView = (DatePickerView) window.findViewById(R.id.datePickerView);
  10.  
  11. //打开页面时需要选中的日期 TODO
  12. datePickerView.setDate(2015, 5, 11);
  13. // datePickerView.setDate(birthdayArray[0], birthdayArray[1], birthdayArray[2]);
  14.  
  15. final int[] birthdayArray = new int[3];
  16. datePickerView.addOnSelectedChangingListener(new DatePickerView.OnSelectedChangedListener() {
  17. @Override
  18. public void OnSelectedChanged(int[] oldValue, int[] newValue) {
  19. birthdayArray[0] = newValue[0];
  20. birthdayArray[1] = newValue[1];
  21. birthdayArray[2] = newValue[2];
  22. }
  23. });
  24. window.findViewById(R.id.tvCancel).setOnClickListener(new View.OnClickListener() {
  25. @Override
  26. public void onClick(View view) {
  27. dialog.dismiss();
  28. }
  29. });
  30. window.findViewById(R.id.tvOK).setOnClickListener(new View.OnClickListener() {
  31. @Override
  32. public void onClick(View view) {
  33. dialog.dismiss();
  34.  
  35. btn0.setText(birthdayArray[0] + "年" + birthdayArray[1] + "月" + birthdayArray[2] + "日");
  36. }
  37. });
  38.  
  39. }

1.WheelView 源码(有修改)

2.xml布局文件

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <!--widget_date_picker.xml-->
  3. <!--注意修改页面自定义控件的包名-->
  4. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  5. android:layout_width="match_parent"
  6. android:layout_height="wrap_content"
  7. android:orientation="horizontal">
  8.  
  9. <de.bvb.rxdemo.widget.DateSelectWidget.wheelview.WheelView
  10. android:id="@+id/wheelViewYear"
  11. android:layout_width="0dp"
  12. android:layout_height="match_parent"
  13. android:layout_gravity="center"
  14. android:layout_weight="1"/>
  15.  
  16. <de.bvb.rxdemo.widget.DateSelectWidget.wheelview.WheelView
  17. android:id="@+id/wheelViewMonth"
  18. android:layout_width="0dp"
  19. android:layout_height="match_parent"
  20. android:layout_gravity="center"
  21. android:layout_weight="1"/>
  22.  
  23. <de.bvb.rxdemo.widget.DateSelectWidget.wheelview.WheelView
  24. android:id="@+id/wheelViewDay"
  25. android:layout_width="0dp"
  26. android:layout_height="match_parent"
  27. android:layout_gravity="center"
  28. android:layout_weight="1"/>
  29.  
  30. </LinearLayout>
  1. <?xml version="1.0" encoding="utf-8"?>
  2. <!--dialog_change_date.xml-->
  3. <!--注意修改页面自定义控件的包名-->
  4. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  5. android:layout_width="match_parent"
  6. android:layout_height="match_parent"
  7. android:background="@android:color/transparent"
  8. android:gravity="bottom"
  9. android:orientation="vertical">
  10.  
  11. <LinearLayout
  12. android:layout_width="match_parent"
  13. android:layout_height="wrap_content"
  14. android:background="@android:color/white"
  15. android:orientation="vertical">
  16.  
  17. <LinearLayout
  18. android:layout_width="match_parent"
  19. android:layout_height="48dp"
  20. android:orientation="horizontal">
  21.  
  22. <TextView
  23. android:id="@+id/tvCancel"
  24. android:layout_width="0dp"
  25. android:layout_height="match_parent"
  26. android:layout_weight="1"
  27. android:background="#F9F9F9"
  28. android:gravity="center"
  29. android:text="取消"
  30. android:textColor="#43AAFC"/>
  31.  
  32. <View
  33. android:layout_width="1px"
  34. android:layout_height="match_parent"
  35. android:background="#D7D7D7"/>
  36.  
  37. <TextView
  38. android:id="@+id/tvOK"
  39. android:layout_width="0dp"
  40. android:layout_height="match_parent"
  41. android:layout_weight="1"
  42. android:background="#F9F9F9"
  43. android:gravity="center"
  44. android:text="确定"
  45. android:textColor="#43AAFC"/>
  46.  
  47. </LinearLayout>
  48.  
  49. <View
  50. android:layout_width="match_parent"
  51. android:layout_height="1px"
  52. android:background="#D7D7D7"/>
  53.  
  54. <de.bvb.rxdemo.widget.DateSelectWidget.DatePickerView
  55. android:id="@+id/datePickerView"
  56. android:layout_width="match_parent"
  57. android:layout_height="wrap_content"/>
  58.  
  59. </LinearLayout>
  60. </LinearLayout>

3.java文件

  1. package de.bvb.rxdemo.widget.DateSelectWidget;
  2.  
  3. import android.content.Context;
  4. import android.util.AttributeSet;
  5. import android.view.LayoutInflater;
  6. import android.view.View;
  7. import android.widget.LinearLayout;
  8. import android.widget.TextView;
  9.  
  10. import java.util.ArrayList;
  11.  
  12. import de.bvb.rxdemo.R;
  13. import de.bvb.rxdemo.widget.DateSelectWidget.wheelview.OnWheelChangedListener;
  14. import de.bvb.rxdemo.widget.DateSelectWidget.wheelview.OnWheelScrollListener;
  15. import de.bvb.rxdemo.widget.DateSelectWidget.wheelview.WheelView;
  16. import de.bvb.rxdemo.widget.DateSelectWidget.wheelview.adapter.AbstractWheelTextAdapter1;
  17.  
  18. public class DatePickerView extends LinearLayout {
  19.  
  20. private static final int YEAR_MIN = 1950;
  21. private static final int YEAR_MAX = 2020;
  22.  
  23. private int year = YEAR_MIN;
  24. private int month = 1;
  25. private int day = 1;
  26.  
  27. private ArrayList<Integer> yearList = new ArrayList<>(YEAR_MAX - YEAR_MIN + 1);
  28. private ArrayList<Integer> monthList = new ArrayList<>(12);
  29. private ArrayList<Integer> dayList = new ArrayList<>(31);
  30.  
  31. private DateTextAdapter yearAdapter;
  32. private DateTextAdapter monthAdapter;
  33. private DateTextAdapter dayAdapter;
  34.  
  35. private Context context;
  36. private WheelView wheelViewYear;
  37. private WheelView wheelViewMonth;
  38. private WheelView wheelViewDay;
  39.  
  40. public DatePickerView(Context context) {
  41. this(context, null);
  42. }
  43.  
  44. public DatePickerView(Context context, AttributeSet attrs) {
  45. this(context, attrs, 0);
  46. }
  47.  
  48. public DatePickerView(Context context, AttributeSet attrs, int defStyleAttr) {
  49. super(context, attrs, defStyleAttr);
  50. this.context = context;
  51. init();
  52. }
  53.  
  54. private void init() {
  55. for (int i = YEAR_MIN; i < YEAR_MAX + 1; i++) {
  56. yearList.add(i);
  57. }
  58. for (int i = 1; i < 13; i++) {
  59. monthList.add(i);
  60. }
  61. for (int i = 1; i < 32; i++) {
  62. dayList.add(i);
  63. }
  64.  
  65. LayoutInflater.from(context).inflate(R.layout.widget_date_picker, this);
  66. // View.inflate(context, R.layout.widget_date_picker, this);
  67.  
  68. wheelViewYear = (WheelView) findViewById(R.id.wheelViewYear);
  69. wheelViewMonth = (WheelView) findViewById(R.id.wheelViewMonth);
  70. wheelViewDay = (WheelView) findViewById(R.id.wheelViewDay);
  71.  
  72. wheelViewYear.setCyclic(true);// 可循环滚动
  73. wheelViewMonth.setCyclic(true);// 可循环滚动
  74. wheelViewDay.setCyclic(true);// 可循环滚动
  75.  
  76. yearAdapter = new DateTextAdapter(context);
  77. monthAdapter = new DateTextAdapter(context);
  78. dayAdapter = new DateTextAdapter(context);
  79.  
  80. yearAdapter.setList(yearList);
  81. monthAdapter.setList(monthList);
  82. dayAdapter.setList(dayList);
  83.  
  84. wheelViewYear.setViewAdapter(yearAdapter);
  85. wheelViewMonth.setViewAdapter(monthAdapter);
  86. wheelViewDay.setViewAdapter(dayAdapter);
  87.  
  88. wheelViewYear.addChangingListener(new OnWheelChangedListener() {
  89. @Override
  90. public void onChanged(WheelView wheel, int oldValue, int newValue) {
  91. year = YEAR_MIN + newValue;
  92. int days = calcDay(year, month); // days=28
  93. dayList = getDayList(days);
  94. dayAdapter.setList(dayList);
  95. if (day > days) {
  96. dayAdapter.currentIndex = days - 1;
  97. wheelViewDay.setCurrentItem(dayAdapter.currentIndex);
  98. } else {
  99. dayAdapter.currentIndex = day - 1; // day = 30
  100. }
  101.  
  102. if (onSelectedChangedListener != null) {
  103. onSelectedChangedListener.OnSelectedChanged(parseInt2Array(YEAR_MIN + oldValue, month, day), getSelectDate());
  104. }
  105. }
  106. });
  107.  
  108. wheelViewMonth.addChangingListener(new OnWheelChangedListener() {
  109. @Override
  110. public void onChanged(WheelView wheel, int oldValue, int newValue) {
  111. month = 1 + newValue;
  112. int days = calcDay(year, month); // days=28
  113. dayList = getDayList(days);
  114. dayAdapter.setList(dayList);
  115. if (day > days) {
  116. dayAdapter.currentIndex = days - 1;
  117. wheelViewDay.setCurrentItem(dayAdapter.currentIndex);
  118. } else {
  119. dayAdapter.currentIndex = day - 1; // day = 30
  120. }
  121.  
  122. if (onSelectedChangedListener != null) {
  123. onSelectedChangedListener.OnSelectedChanged(parseInt2Array(year, 1 + oldValue, day), getSelectDate());
  124. }
  125. }
  126. });
  127.  
  128. wheelViewDay.addChangingListener(new OnWheelChangedListener() {
  129. @Override
  130. public void onChanged(WheelView wheel, int oldValue, int newValue) {
  131. day = 1 + newValue;
  132. if (onSelectedChangedListener != null) {
  133. onSelectedChangedListener.OnSelectedChanged(parseInt2Array(year, month, oldValue + 1), getSelectDate());
  134. }
  135. }
  136. });
  137.  
  138. wheelViewYear.addScrollingListener(onWheelScrollListener);
  139. wheelViewMonth.addScrollingListener(onWheelScrollListener);
  140. wheelViewDay.addScrollingListener(onWheelScrollListener);
  141. }
  142.  
  143. OnWheelScrollListener onWheelScrollListener = new OnWheelScrollListener() {
  144. @Override
  145. public void onScrollingStarted(WheelView wheel) {
  146.  
  147. }
  148.  
  149. @Override
  150. public void onScrollingFinished(WheelView wheel) {
  151. setTextViewStyle();
  152. }
  153. };
  154.  
  155. private void setTextViewStyle() {
  156. setTextViewSize(year + "", yearAdapter);
  157. setTextViewSize(month + "", monthAdapter);
  158. setTextViewSize(day + "", dayAdapter);
  159. }
  160.  
  161. private void setTextViewSize(String currentItemText, AbstractWheelTextAdapter1 adapter) {
  162. ArrayList<View> arrayList = adapter.getTextViews();
  163. int size = arrayList.size();
  164. String currentText;
  165. TextView textView;
  166. boolean current;
  167. for (int i = 0; i < size; i++) {
  168. textView = (TextView) arrayList.get(i);
  169. currentText = textView.getText().toString();
  170. current = currentItemText.equals(currentText);
  171. textView.setTextColor(current ? adapter.selected_text_color : adapter.un_selected_text_color);
  172. textView.setTextSize(current ? adapter.selected_text_size : adapter.un_selected_text_size);
  173. }
  174. }
  175.  
  176. /**
  177. * 设置控件的初始值
  178. *
  179. * @param year
  180. * @param month
  181. * @param day
  182. */
  183. public void setDate(int year, int month, int day) {
  184. //验证合法性
  185. if (year > YEAR_MAX || year < YEAR_MIN) {
  186. year = YEAR_MIN;
  187. // throw new RuntimeException("年份必须在[" + YEAR_MIN + "," + YEAR_MAX + "]之间");
  188. }
  189. if (month > 12 || month < 1) {
  190. month = 1;
  191. // throw new RuntimeException("月份份必须在[" + 1 + "," + 12 + "]之间");
  192. }
  193. final int days = calcDay(year, month);
  194. if (day > days || day < 1) {
  195. day = 1;
  196. // throw new RuntimeException("日期份必须在[" + 1 + "," + days + "]之间");
  197. }
  198.  
  199. this.year = year;
  200. this.month = month;
  201. this.day = day;
  202.  
  203. yearAdapter.currentIndex = DatePickerView.this.year - YEAR_MIN;
  204. monthAdapter.currentIndex = DatePickerView.this.month - 1;
  205. dayAdapter.currentIndex = DatePickerView.this.day - 1;
  206.  
  207. wheelViewYear.setCurrentItem(yearAdapter.currentIndex);
  208. wheelViewMonth.setCurrentItem(monthAdapter.currentIndex);
  209. wheelViewDay.setCurrentItem(dayAdapter.currentIndex);
  210. }
  211.  
  212. public void addOnSelectedChangingListener(OnSelectedChangedListener onSelectedChangedListener) {
  213. this.onSelectedChangedListener = onSelectedChangedListener;
  214. }
  215.  
  216. private OnSelectedChangedListener onSelectedChangedListener;
  217.  
  218. public interface OnSelectedChangedListener {
  219. void OnSelectedChanged(int[] oldValue, int[] newValue);
  220. }
  221.  
  222. private int[] parseInt2Array(int year, int month, int day) {
  223. return new int[]{year, month, day};
  224. }
  225.  
  226. private int[] getSelectDate() {
  227. return new int[]{year, month, day};
  228. }
  229.  
  230. private ArrayList<Integer> getDayList(int days) {
  231. if (days <= 0) {
  232. return null;
  233. }
  234. ArrayList<Integer> list = new ArrayList(days);
  235. for (int i = 1; i < days + 1; i++) {
  236. list.add(i);
  237. }
  238. return list;
  239. }
  240.  
  241. private int calcDay(int year, int month) {
  242. int days = 0;
  243. switch (month) {
  244. case 1:
  245. case 3:
  246. case 5:
  247. case 7:
  248. case 8:
  249. case 10:
  250. case 12:
  251. days = 31;
  252. break;
  253. case 4:
  254. case 6:
  255. case 9:
  256. case 11:
  257. days = 30;
  258. break;
  259. case 2:
  260. days = (year % 400 == 0 || (year % 100 != 0 && year % 4 == 0)) ? 29 : 28;
  261. break;
  262. }
  263. return days;
  264. }
  265.  
  266. private class DateTextAdapter extends AbstractWheelTextAdapter1 {
  267. ArrayList<Integer> list;
  268.  
  269. public DateTextAdapter(Context context) {
  270. super(context, android.R.layout.simple_list_item_1);
  271. // super(context, R.layout.item_birth_year);
  272. // setItemTextResource(R.id.tempValue);
  273.  
  274. // item_birth_year.xml 内容如下
  275. // <?xml version="1.0" encoding="utf-8"?>
  276. // <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  277. // android:layout_width="match_parent"
  278. // android:layout_height="35dip"
  279. // android:gravity="center"
  280. // android:orientation="horizontal">
  281. // <TextView
  282. // android:id="@+id/tempValue"
  283. // android:layout_width="match_parent"
  284. // android:layout_height="match_parent"
  285. // android:gravity="center"
  286. // android:textColor="#ffff0000"/>
  287. // </LinearLayout>
  288. }
  289.  
  290. public void setList(ArrayList<Integer> list) {
  291. this.list = list;
  292. notifyDataChangedEvent();
  293. }
  294.  
  295. @Override
  296. protected CharSequence getItemText(int index) {
  297. return list == null ? "" : String.valueOf(list.get(index));
  298. }
  299.  
  300. @Override
  301. public int getItemsCount() {
  302. return list == null ? 0 : list.size();
  303. }
  304. }
  305. }

Android 自定义控件之 日期选择控件的更多相关文章

  1. 用c/c++混合编程方式为ios/android实现一个自绘日期选择控件(一)

    本文为原创,如有转载,请注明出处:http://www.cnblogs.com/jackybu 前言 章节: 1.需求描述以及c/c++实现日期和月历的基本操作 2.ios实现自绘日期选择控件 3.a ...

  2. Android自定义View(RollWeekView-炫酷的星期日期选择控件)

    转载请标明出处: http://blog.csdn.net/xmxkf/article/details/53420889 本文出自:[openXu的博客] 目录: 1分析 2定义控件布局 3定义Cus ...

  3. Android自定义控件之自定义组合控件

    前言: 前两篇介绍了自定义控件的基础原理Android自定义控件之基本原理(一).自定义属性Android自定义控件之自定义属性(二).今天重点介绍一下如何通过自定义组合控件来提高布局的复用,降低开发 ...

  4. js 跨域的问题 (同一个主域名不同的二级域名下的跨域问题) 解决 WdatePicker.js my97日期选择控件

    例如域名是  a.xx.com  和 b.xx.com    如果一个页面中引入多个iframe,要想能够操作所有iframe,必须都得设置相同domain. 如果iframe的时候  a包含b  为 ...

  5. JQuery好用的日期选择控件 DatePicker

    近期发现一个很好的基于JQ的前端UI日期选择控件Jquery.DatePicker.js 下载地址:jquery.DatePIcker.js 演示地址:DatePicker - 基于jQuery 1. ...

  6. [Ext JS 4] 实战之 带week(星期)的日期选择控件(三)

    前言 在 [Ext JS 4] 实战之 带week(星期)的日期选择控件(二) 的最后,有提到一个解决方案. 不过这方案有一个条件  ==> “2. 每年的周数从(1-52), 如果超过52 周 ...

  7. Swift - 日期选择控件(UIDatePicker)的用法

    1,使用storyboard创建日期选择控件 首先我们将一个UIDatePicker控件和一个按钮直接添加到Main.Storyboard上.该按钮是为了点击时弹出提示框显示当前选择的日期和时间. 同 ...

  8. 取消layUI中日期选择控件默认填充日期

    input标签中使用日期选择控件填写,加载时默认填充当前日期, 标签设置了placeholder="请选择" autocomplete="off",但是并没有效 ...

  9. Ionic实战六:日期选择控件

    onic日期选择控件,用于ionic项目开发中的日期选择以及日期插件   

随机推荐

  1. oracle 编译无效对象

    在数据库中,会存在一些无效的对象,导致这种现象的发生原因很多,其中最常见的就是数据库升级(例如修改了表的结构),迁移而引起. 编译无效对象的方式: 1 使用alter **** compile 语句进 ...

  2. Restful API 架构与设计参考原则

    1. 什么是RESTREST全称是Representational State Transfer,中文意思是表述(编者注:通常译为表征)性状态转移. 它首次出现在2000年Roy Fielding的博 ...

  3. ES6展开运算符数组合并,函数传参

    定义: .展开运算符允许一个表达式在某处展开. 使用场景 1.展开函数在多个参数的地方使用 .意指用于函数传参 2.多个元素的地方使用,意指用于数组字面量 3.多个边框的地方使用,意指用于解构赋值 函 ...

  4. 使用PHP实现查找附近的人

    https://zhuanlan.zhihu.com/p/31380780 LBS(基于位置的服务) 查找附近的人有个更大的专有名词叫做LBS(基于位置的服务),LBS是指是指通过电信移动运营商的无线 ...

  5. struts2之Action与JSP相互数据传递

    package com.loaderman.crm.action; import com.loaderman.crm.entity.User; import com.loaderman.crm.ser ...

  6. [Java复习] MQ

    1. 为什么要用MQ? 解耦,异步,削峰 2. MQ的优点和缺点? 优点: 解耦.异步.削峰 缺点: 1. 系统可用性降低. 外部依赖越多,越容易挂.如果MQ挂了,怎么处理? 2. 系统复杂度提高. ...

  7. html js 遮罩层

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  8. LeetCode_70. Climbing Stairs

    70. Climbing Stairs Easy You are climbing a stair case. It takes n steps to reach to the top. Each t ...

  9. vs2015配置link.exe环境变量

    https://www.cnblogs.com/johnwii/p/4966086.html

  10. caffe dropout解读

    先上caffe dropout_layer.cpp源码,如下: // LayerSetUp DCHECK(threshold_ > 0.); DCHECK(threshold_ < 1.) ...