自定义的DataPicker和TimePicker(日期选择器和时间选择器)
来源:互联网 发布:老子化胡 知乎 编辑:程序博客网 时间:2024/06/06 12:44
公司项目里用到了TimePicker和DataPicker,但是因为项目用的版本较低,所以TimePicker和DataPicker显示出来的样式不怎么美观,那种黑白的,实在看不下去,于是自己定义了两个控件,拿出来分享一下
首先封装一个输入框,加减可控制:
private void onCreat() { view = LayoutInflater.from(this.getContext()).inflate(R.layout.dialog_picker, this, true); initView(); }
监听点击事件和输入事件,将接口透出去:
/** * 接口 * imgAdd + * imgMinus — */ public interface OnClickListener { //加 void add(String inputStr); //减 void minus(String inputStr); //输入的内容的监听 void textChange(Editable str); }
点击事件
//点击事件 加号 imgAdd.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { if (onClickListener != null) { String inputStr = edInput.getText().toString(); onClickListener.add(inputStr); } } }); //点击事件 减号 imgMinus.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { if (onClickListener != null) { String inputStr = edInput.getText().toString(); onClickListener.minus(inputStr); } } });
输入事件监听,之前是准备让EditText中的值也可以手动输入,但是这样的话会牵涉到焦点的获取之类的,还有更多的逻辑判断,项目当时有点紧,就没有让EditText设置可输入,有兴趣的小伙伴们可以自己加上去
edInput.addTextChangedListener(new TextWatcher() { @Override public void beforeTextChanged(CharSequence s, int start, int count, int after) { } @Override public void onTextChanged(CharSequence s, int start, int before, int count) { } @Override public void afterTextChanged(Editable s) { if (onClickListener != null) { onClickListener.textChange(s); } } });
设置输入的长度 xml中设置了最大显示数目
public void setInputLenth(int inputLenth) { if (inputLenth == 0 || String.valueOf(inputLenth).length() == 0 || "".equals(String.valueOf(inputLenth))) { edInput.setFilters(new InputFilter[]{new InputFilter.LengthFilter(4)}); } else { //最大输入长度 edInput.setFilters(new InputFilter[]{new InputFilter.LengthFilter(inputLenth)}); } }
因为封装的这个控件会分别用到DataPicker和Timeker 中,所以要实用多种情况,控件中间不光是一个EditText,EditText 的右面还有一个TextView,宽度设置自适应,这样就还可以通过代码直接设置显示的情况,从而实现作用于不同的场景
/** * 设置显示的类型 * * @param inputType tvType 显示的值 "年","月","日" */ public void setInputType(String inputType) { tvType.setText(inputType); }
设置EditText 中输入的值,一般用来设置默认的显示值
/** * 设置EditText显示的内容 * * @param string EditText要显示的值 */ public void setEdInput(String string) { edInput.setText(string); }
获得EditText中输入的值
public String getEdInput() { return edInput.getText().toString(); }
现在这一部分就基本完成了,接着就要开始封装TimePicker了
封装TimePickerDialog
因为我们的需求是需要开始时间和结束时间两个时间点,所以我直接把开始时间和结束时间封装在了一起,并且没有区分12时计时法和24时计时法,默认成24时计时法,其实如果想加上的话只需要把定义一个全局变量,把接口透出去,就可以了,这里就不做赘述了
view = LayoutInflater.from(getContext()).inflate(R.layout.dialog_time, null); hourStart = (MyDatePickerDia) view.findViewById(R.id.date_hour_start); hourEnd = (MyDatePickerDia) view.findViewById(R.id.date_hour_end); minuteStart = (MyDatePickerDia) view.findViewById(R.id.date_minute_start); minuteEnd = (MyDatePickerDia) view.findViewById(R.id.date_minute_end); tvDate = (TextView) view.findViewById(R.id.tv_date); tvOk = (TextView) view.findViewById(R.id.ok); tvOk.setClickable(true); tvCancle = (TextView) view.findViewById(R.id.cancel); tvCancle.setClickable(true); //点击确定的时候把每个之前封装的控件中的值取到,然后用“:”和"-"拼接之后传出去 tvOk.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { if (onClickListener != null) { int hs = Integer.parseInt(hourStart.getEdInput()); int he = Integer.parseInt(hourEnd.getEdInput()); int ms = Integer.parseInt(minuteStart.getEdInput()); int me = Integer.parseInt(minuteEnd.getEdInput()); String time = String.format(format, hs) + ":" + String.format(format, ms) + "-" + String.format(format, he) + ":" + String.format(format, me); onClickListener.clickOk(time); } dismiss(); } });//点击取消的时候,将时间设置成默认,这里是将开始时间默认设置为8:00,结束时间默认设置成18:00 tvCancle.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { if (onClickListener != null) { String time = "08:00-18:00"; onClickListener.clickCancle(time); } dismiss(); } });
透出的接口
/** * 接口 */ public interface OnClickListener { void clickOk(String ok); void clickCancle(String cancle); }
设置确定按钮和取消按钮显示的字符串
/** * 设置取消按钮的显示内容 * * @param cancle 显示的内容 */ public void setTextCancle(String cancle) { tvCancle.setText(cancle); } /** * 设置确定按钮的显示内容 * * @param ok */ public void steTextOk(String ok) { tvOk.setText(ok); }
设置Dialog的样式,
/** * dialog 的宽高的设置 */ private void resize() { Window dialogWindow = this.getWindow(); int width = WindowUtils.getScreenWidth(dialogWindow); WindowManager.LayoutParams p = dialogWindow.getAttributes(); // 获取对话框当前的参数值 p.width = (int) (width * 0.85); // 宽度设置为屏幕的0.85 dialogWindow.setAttributes(p); }
设置Dialog的标题
/** * 设置标题 */ public void setTittle(String string) { tvDate.setText(string); }
准备工作算是基本完成了,现在该开始写逻辑了
上班的时间中的小时的操作
/** * 上班时间 -小时 */ private void hourStartSetting() { //设置最多显示两位 hourStart.setInputLenth(2); //不足两位十位补零 默认设置为 08 hourStart.setEdInput(String.format(format, 8)); hourStart.setOnClickListener(new MyDatePickerDia.OnClickListener() { @Override public void add(String inputStr) { hourAdd(true); } @Override public void minus(String inputStr) { hourMinus(true); } @Override public void textChange(Editable str) { } }); }
上班分钟的操作
/** * 上班时间 -分钟 */ private void minuteStartSetting() { minuteStart.setInputLenth(2); minuteStart.setEdInput(String.format(format, 0)); minuteStart.setOnClickListener(new MyDatePickerDia.OnClickListener() { @Override public void add(String inputStr) { minuteAdd(true); } @Override public void minus(String inputStr) { minuteMinus(true); } @Override public void textChange(Editable str) { } }); }
下班小时操作
/** * 下班时间 -小时 */ private void hourEndSetting() { //设置最多显示两位 hourStart.setInputLenth(2); //不足两位十位补零 默设置为 18 hourEnd.setEdInput(String.format(format, 18)); hourEnd.setOnClickListener(new MyDatePickerDia.OnClickListener() { @Override public void add(String inputStr) { hourAdd(false); } @Override public void minus(String inputStr) { hourMinus(false); } @Override public void textChange(Editable str) { } }); }
下班分钟的操作
/** * 下班时间 -分钟 */ private void minuEndSetting() { minuteEnd.setInputLenth(2); minuteEnd.setEdInput(String.format(format, 0)); minuteEnd.setOnClickListener(new MyDatePickerDia.OnClickListener() { @Override public void add(String inputStr) { minuteAdd(false); } @Override public void minus(String inputStr) { minuteMinus(false); } @Override public void textChange(Editable str) { } }); }
小时+
/** * 小时 + * * @param type 类型 true 开始 false 结束 */ private void hourAdd(boolean type) { int hour = 0; if (type) { hour = Integer.parseInt(hourStart.getEdInput()); } else { hour = Integer.parseInt(hourEnd.getEdInput()); } if (hour == 23) { hour = 0; } else { hour++; } String Hour = String.format(format, hour); if (type) { hourStart.setEdInput(Hour); } else { hourEnd.setEdInput(Hour); } }
小时-
/** * 小时 - * * @param type 类型 true 开始 false 结束 */ private void hourMinus(boolean type) { int hour = 0; if (type) { hour = Integer.parseInt(hourStart.getEdInput()); } else { hour = Integer.parseInt(hourEnd.getEdInput()); } if (hour == 0) { hour = 23; } else { hour--; } String Hour = String.format(format, hour); if (type) { hourStart.setEdInput(Hour); return; } hourEnd.setEdInput(Hour); }
分钟+
/** * 分钟 + * * @param type 类型 true 开始 false 结束 */ private void minuteAdd(boolean type) { int minute = 0; if (type) { minute = Integer.parseInt(minuteStart.getEdInput()); } else { minute = Integer.parseInt(minuteEnd.getEdInput()); } if (minute == 59) { minute = 0; if (type) { hourAdd(true); } else { hourAdd(false); } } else { minute++; } if (type) { minuteStart.setEdInput(String.format(format, minute)); return; } minuteEnd.setEdInput(String.format(format, minute)); }
分钟-
/** * 分钟减 * * @param type 类型 true 开始 false 结束 */ private void minuteMinus(boolean type) { int minute = 0; if (type) { minute = Integer.parseInt(minuteStart.getEdInput()); } else { minute = Integer.parseInt(minuteEnd.getEdInput()); } if (minute == 0) { minute = 59; if (type) { hourMinus(true); } else { hourMinus(false); } } else { minute--; } if (type) { minuteStart.setEdInput(String.format(format, minute)); return; } minuteEnd.setEdInput(String.format(format, minute)); }
到这里基本的逻辑也就完成的差不多了,TimePickerDialog也就基本完成了
接下来我们接着封装DataPickerDialog
DataPicker相比TimePicker稍微麻烦一点,原因就是DataPicker中牵扯到了闰年平年,以及12个月份每个月的天数不同
同样,首先,我们先 创建Diallog
view = LayoutInflater.from(getContext()).inflate(R.layout.dialog_date, null); year = (MyDatePickerDia) view.findViewById(R.id.date_year); month = (MyDatePickerDia) view.findViewById(R.id.date_month); day = (MyDatePickerDia) view.findViewById(R.id.date_day); tvDate = (TextView) view.findViewById(R.id.tv_date); tvOk = (TextView) view.findViewById(R.id.ok); tvOk.setClickable(true); tvCancle = (TextView) view.findViewById(R.id.cancel); tvCancle.setClickable(true); tvOk.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { if (onClickListener != null) { onClickListener.clickOk(tittleShow()); } dismiss(); } }); tvCancle.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { if (onClickListener != null) { String now = String.valueOf(calendar.get(Calendar.YEAR)) + "年-" + String.format(format, calendar.get(Calendar.MONTH) + 1) + "月-" + String.format(format, calendar.get(Calendar.DAY_OF_MONTH)) + "日"; onClickListener.clickCancle(now); } dismiss(); } });
与TimePickerDialog差不多,不做赘述
这里主要写逻辑代码
年的设置
/** * 年的设置 */ private void yearSetting() { year.setInputType("年"); year.setInputLenth(4); year.setEdInput(String.valueOf(calendar.get(Calendar.YEAR))); year.setOnClickListener(new MyDatePickerDia.OnClickListener() { @Override public void add(String inputStr) { yearAdd(inputStr); tittleShow(); } @Override public void minus(String inputStr) { yearMinus(inputStr); tittleShow(); } @Override public void textChange(Editable str) { tvDate.setText(str); } }); }
月的设置
/** * 月的设置 */ private void monthSetting() { month.setInputType("月"); month.setInputLenth(2); month.setEdInput(String.format(format, calendar.get(Calendar.MONTH) + 1)); month.setOnClickListener(new MyDatePickerDia.OnClickListener() { @Override public void add(String inputStr) { monthAdd(inputStr); tittleShow(); } @Override public void minus(String inputStr) { monthMinus(inputStr); tittleShow(); } @Override public void textChange(Editable str) { } }); }
天的设置
/** * 天的设置 */ private void daySetting() { day.setInputType("日"); day.setInputLenth(2); day.setEdInput(String.format(format, calendar.get(Calendar.DAY_OF_MONTH))); day.setOnClickListener(new MyDatePickerDia.OnClickListener() { @Override public void add(String inputStr) { dayAdd(inputStr); tittleShow(); } @Override public void minus(String inputStr) { dayMinus(inputStr); tittleShow(); } @Override public void textChange(Editable str) { } }); }
年+
/** * 年 + * * @param add */ private void yearAdd(String add) { int input = 0; if (add.length() == 0 || "".equals(add) || Integer.parseInt(add) < 1900) { add = "1900"; year.setEdInput(add); } else { input = Integer.parseInt(add); input++; if (input > 2100) { input = 2100; } yearChange(input); year.setEdInput(String.valueOf(input)); } }
年-
/** * 年 - * * @param minus */ private void yearMinus(String minus) { int input = 0; if (minus.length() == 0 || "".equals(minus) || Integer.parseInt(minus) < 1900) { minus = "1900"; year.setEdInput(minus); } else { input = Integer.parseInt(minus); if (input > 2101) { input = 2101; } input--; if (input < 1900) { input = 1900; } yearChange(input); year.setEdInput(String.valueOf(input)); } }
月 +
/** * 月 + * * @param add */ private void monthAdd(String add) { int input = 0; if ((add.length() == 0) || "".equals(add) || (Integer.parseInt(add) > 12) || (Integer.parseInt(add) < 1)) { add = String.format(format, calendar.get(Calendar.MONTH)); month.setEdInput(add); } else { input = Integer.parseInt(add); if (input == 12) { input = 1; //月份变化对年的影响 +1 yearAdd(year.getEdInput()); } else { input++; //月份变化对日的影响 monthChange(input); } month.setEdInput(String.format(format, input)); } }
月-
/** * 月 - * * @param minus */ private void monthMinus(String minus) { int input = 0; if ((minus.length() == 0) || "".equals(minus) || (Integer.parseInt(minus) > 12) || (Integer.parseInt(minus) < 1)) { minus = String.format(format, calendar.get(Calendar.MONTH)); month.setEdInput(minus); return; } input = Integer.parseInt(minus); if (input == 1) { input = 12; //月份变化对年的影响 -1 yearMinus(year.getEdInput()); } else { input--; //月份变化对日的影响 monthChange(input); } month.setEdInput(String.format(format, input)); }
日+
/** * 日 + * * @param add */ private void dayAdd(String add) { int y = Integer.parseInt(year.getEdInput()); int m = Integer.parseInt(month.getEdInput()); int d = Integer.parseInt(add); if ("".equals(add) || add.length() == 0 || d > 31 || d < 1) { month.setEdInput(String.format(format, calendar.get(Calendar.MONTH) + 1)); day.setEdInput(String.format(format, calendar.get(Calendar.DAY_OF_MONTH))); } else if (d == 31) { monthAdd(String.format(format, m)); day.setEdInput(String.format(format, 1)); } else if (d == 30) { if (m == 1 || m == 3 || m == 5 || m == 7 || m == 8 || m == 10 || m == 12) { d++; day.setEdInput(String.format(format, d)); } else { monthAdd(String.format(format, m)); day.setEdInput(String.format(format, 1)); } } else if (d == 29) { if (m == 2) { monthAdd(String.format(format, m)); day.setEdInput(String.format(format, 1)); } else { d++; day.setEdInput(String.format(format, d)); } } else if (d == 28) { if (m == 2) { if (isLeapYear(y)) { d++; day.setEdInput(String.format(format, d)); } else { monthAdd(String.format(format, m)); day.setEdInput(String.format(format, 1)); } } else { d++; day.setEdInput(String.format(format, d)); } } else { d++; day.setEdInput(String.format(format, d)); } }
日-
/** * 日 — * * @param minus */ private void dayMinus(String minus) { int y = Integer.parseInt(year.getEdInput()); int m = Integer.parseInt(month.getEdInput()); int d = Integer.parseInt(minus); if ("".equals(minus) || minus.length() == 0 || d > 31 || d < 1) { day.setEdInput(String.format(format, calendar.get(Calendar.DAY_OF_MONTH))); } else if (d == 1) { //4,6,9,11四个月是30天,上一个月一号减1,变成30号 if (m == 5 || m == 7 || m == 10 || m == 12) { day.setEdInput(String.format(format, 30)); } else if (m == 3) { if (isLeapYear(y)) { day.setEdInput(String.format(format, 29)); } else { day.setEdInput(String.format(format, 28)); } } else { day.setEdInput(String.format(format, 31)); } monthMinus(String.format(format, m)); } else if (d == 31) { if (m == 2) { if (isLeapYear(y)) { day.setEdInput(String.format(format, 29)); } else { day.setEdInput(String.format(format, 28)); } } else if (m == 4 || m == 6 || m == 9 || m == 11) { day.setEdInput(String.format(format, 30)); } else { d--; day.setEdInput(String.format(format, d)); } } else if (d == 30) { if (m == 2 && !isLeapYear(y)) { day.setEdInput(String.format(format, 28)); } else { d--; day.setEdInput(String.format(format, d)); } } else { d--; day.setEdInput(String.format(format, d)); } }
不同的月份对天的影响不同
/** * 月份改变对日的影响 * * @param month 月份 */ private void monthChange(int month) { //2月情况特殊,需分平年闰年,特殊处理 if (month == 2) { if (isLeapYear(Integer.parseInt(year.getEdInput()))) { if (Integer.parseInt(day.getEdInput()) > 29) { day.setEdInput("29"); } } else { if (Integer.parseInt(day.getEdInput()) > 28) { day.setEdInput("28"); } } //4,6,9,11一个月最多三十天 } else if (month == 4 || month == 6 || month == 9 || month == 11) { if (Integer.parseInt(day.getEdInput()) > 30) { day.setEdInput("30"); } } }
不同的年份对天的影响也不一样
/** * 年份改变对日的影响 * * @param year 年份 */ private void yearChange(int year) { int m = Integer.parseInt(month.getEdInput()); int d = Integer.parseInt(day.getEdInput()); if (m == 2) { if (isLeapYear(year)) { if (d > 29) { day.setEdInput("29"); } } else { if (d > 28) { day.setEdInput("28"); } } } else if (m == 4 || m == 6 || m == 9 || m == 11) { if (d > 30) { day.setEdInput("30"); } } }
基姆拉尔森计算公式 ,根据日期计算星期几
/** * 基姆拉尔森计算公式 Week=(Day + 2*Month + 3*(Month+1)/5 + Year + Year/4 - Year/100 + Year/400) % 7 * * @param y 年 * @param m 月 1,2月需要按13月,14日 * @param d 日 * @return */ private String getWeek(int y, int m, int d) { String Week = "星期"; if (m == 1) { m = 13; } if (m == 2) { m = 14; } int week = (d + 2 * m + 3 * (m + 1) / 5 + y + y / 4 - y / 100 + y / 400) % 7; switch (week) { case 0: Week += "一"; break; case 1: Week += "二"; break; case 2: Week += "三"; break; case 3: Week += "四"; break; case 4: Week += "五"; break; case 5: Week += "六"; break; case 6: Week += "日"; break; default: break; } return Week; }
这样基本上DataPickerDialog就完成了,然后就可以使用了
Demo下载地址
- 自定义的DataPicker和TimePicker(日期选择器和时间选择器)
- TimePicker时间选择器和DatePicker日期选择器
- 日期和时间选择器(DatePicker与TimePicker的用法)
- 时间和日期选择器DatePicker和TimePicker的使用
- Android开发之日期、时间选择器(DatePicker和TimePicker)的功能和用法
- Andorid日期,时间选择器(DatePicker和TimePicker)的功能和用法
- android基本 UI(四)—时间选择器TimePicker和日期选择器 DatePicker
- 时间选择器:DatePicker 和TimePicker
- 时间选择器DatePicker和TimePicker
- Android--DatePicker和TimePicker(日历选择器与时间选择器)
- Android中实现日期时间选择器(DatePicker和TimePicker)
- Android中实现日期时间选择器(DatePicker和TimePicker)
- Android中实现日期时间选择器(DatePicker和TimePicker)
- Android中实现日期时间选择器(DatePicker和TimePicker)
- Android中实现日期时间选择器(DatePicker和TimePicker)
- Android中实现日期时间选择器(DatePicker和TimePicker)
- 时间选择器和日期选择器
- Android DatePicker日期选择器、TimePicker时间选择器的使用
- centos6环境下搭建vpn环境(pptpd)
- 【搜集,整理】Gson解析Json示例,详解
- 使用EventBus代替startActivityForResult向上传递数据
- PHP初级学习——运算符篇
- PS中如何将文字的选区转换成路径
- 自定义的DataPicker和TimePicker(日期选择器和时间选择器)
- 从递归计算到线性计算:C(N)=(2/N)*∑(i: 0->N-1) C(i)+N
- 一文读懂卷积神经网络
- EditText属性大全
- 在Service的内部定义一个start()方法,简化Client端的调用
- shell排序
- CSS3使用边框和背景
- eclipse maven plugin 插件 离线安装 和 配置
- Spring源码下载