揭破android中的闹钟app 二
· 这节,我们通过wheelview来模仿一个简易的正点闹钟。
我这里不说wheelview来龙去脉,只阐述几个简单的方法,如果,想看一看具体wheelview的内容,请看下面两篇文章:
android 时间控件概述和Android 实现 WheelView
要实现正点闹钟,我们需要在程序中加入相应的滚轮的源代码,导入相应的源代码的结构如下所示:

从图,我们可以得出来这样子的结论:
①其滚轮控件不是简简单单的完成日期时间选择,而且可以完成数字,字符串的选择,因此可以做手机的密码箱或者滚动的地址选择控件。
②此简单的框架(类库),运用大量的监听者,可想而知,把经典设计模式——观察者模式运用到了机制。
好了,不东扯葫芦西扯瓢了,说一说本文的重点,时间控件的实现了。老样子,我们看代码:
/**
* @Description: TODO 弹出日期时间选择器
*/
private void showDateTimePicker() {
Calendar calendar = Calendar.getInstance();
final int year = calendar.get(Calendar.YEAR);
current_year = calendar.get(Calendar.YEAR);
int month = calendar.get(Calendar.MONTH);
int day = calendar.get(Calendar.DATE);
// 添加大小月月份并将其转换为list,方便之后的判断
String[] months_big = { "1", "3", "5", "7", "8", "10", "12" };
String[] months_little = { "4", "6", "9", "11" }; final List<String> list_big = Arrays.asList(months_big);
final List<String> list_little = Arrays.asList(months_little); dialog = new BaseDialog(PublicDefine.context);
dialog.setTitle("请选择日期");
// 找到dialog的布局文件 View view = LayoutInflater.from(PublicDefine.context).inflate(
R.layout.date_month_layout, null);
//年
final WheelView wv_year = (WheelView) view.findViewById(R.id.years);
wv_year.setAdapter(new NumericWheelAdapter(start_year, end_year));// 设置"年"的显示数据
wv_year.setCyclic(true);// 可循环滚动
wv_year.setLabel("年");// 添加文字
wv_year.setCurrentItem(year - start_year);// 初始化时显示的数据
// 月
final WheelView wv_month = (WheelView) view.findViewById(R.id.monthes);
wv_month.setAdapter(new NumericWheelAdapter(1, 12));
wv_month.setCyclic(true);
wv_month.setLabel("月");
wv_month.setCurrentItem(month); // 日
final WheelView wv_day = (WheelView) view.findViewById(R.id.days);
wv_day.setCyclic(true);
// 判断大小月及是否闰年,用来确定"日"的数据
if (list_big.contains(String.valueOf(month + 1))) {
wv_day.setAdapter(new NumericWheelAdapter(1, 31));
} else if (list_little.contains(String.valueOf(month + 1))) {
wv_day.setAdapter(new NumericWheelAdapter(1, 30));
} else {
// 闰年
if ((year % 4 == 0 && year % 100 != 0) || year % 400 == 0) {
wv_day.setAdapter(new NumericWheelAdapter(1, 29));
} else {
wv_day.setAdapter(new NumericWheelAdapter(1, 28));
}
}
wv_day.setLabel("日");
wv_day.setCurrentItem(day - 1); // 添加"年"监听
OnWheelChangedListener wheelListener_year = new OnWheelChangedListener() {
public void onChanged(WheelView wheel, int oldValue, int newValue) {
int year_num = newValue + start_year;
// 判断大小月及是否闰年,用来确定"日"的数据
if (list_big.contains(String
.valueOf(wv_month.getCurrentItem() + 1))) {
wv_day.setAdapter(new NumericWheelAdapter(1, 31));
} else if (list_little.contains(String.valueOf(wv_month
.getCurrentItem() + 1))) {
wv_day.setAdapter(new NumericWheelAdapter(1, 30));
} else {
if ((year_num % 4 == 0 && year_num % 100 != 0)
|| year_num % 400 == 0) {
wv_day.setAdapter(new NumericWheelAdapter(1, 29));
} else {
wv_day.setAdapter(new NumericWheelAdapter(1, 28));
}
}
} @Override
public void onEnd() {
// TODO Auto-generated method stub
int day=wv_day.getCurrentItem();
day=day>wv_day.getAdapter().getItemsCount()-1?day-wv_day.getAdapter().getItemsCount():wv_day.getCurrentItem();
wv_day.setCurrentItem(day);
}
};
// 添加"月"监听
OnWheelChangedListener wheelListener_month = new OnWheelChangedListener() {
public void onChanged(WheelView wheel, int oldValue, int newValue) {
int month_num = newValue + 1;
// 判断大小月及是否闰年,用来确定"日"的数据
if (list_big.contains(String.valueOf(month_num))) {
wv_day.setAdapter(new NumericWheelAdapter(1, 31));
} else if (list_little.contains(String.valueOf(month_num))) {
wv_day.setAdapter(new NumericWheelAdapter(1, 30));
} else {
if (((wv_year.getCurrentItem() + start_year) % 4 == 0 && (wv_year
.getCurrentItem() + start_year) % 100 != 0)
|| (wv_year.getCurrentItem() + start_year) % 400 == 0) {
wv_day.setAdapter(new NumericWheelAdapter(1, 29));
} else {
wv_day.setAdapter(new NumericWheelAdapter(1, 28));
}
}
} @Override
public void onEnd() {
// TODO Auto-generated method stub
int day=wv_day.getCurrentItem();
day=day>wv_day.getAdapter().getItemsCount()-1?day-wv_day.getAdapter().getItemsCount():wv_day.getCurrentItem();
wv_day.setCurrentItem(day);
}
};
wv_month.addChangingListener(wheelListener_month);
wv_year.addChangingListener(wheelListener_year);
// 根据屏幕密度来指定选择器字体的大小 int textSize = 20; wv_day.TEXT_SIZE = (int) (textSize*RTools.getSreenDensity(PublicDefine.context));
wv_month.TEXT_SIZE = (int) (textSize*RTools.getSreenDensity(PublicDefine.context));
wv_year.TEXT_SIZE=(int) (textSize*RTools.getSreenDensity(PublicDefine.context));
Button btn_sure = (Button) view.findViewById(R.id.btn_datetime_sure);
Button btn_cancel = (Button) view
.findViewById(R.id.btn_datetime_cancel); // 确定
btn_sure.setOnClickListener(new OnClickListener() { @Override
public void onClick(View arg0) {
// TODO Auto-generated method stub
// 如果是个数,则显示为"02"的样式
String parten = "00";
DecimalFormat decimal = new DecimalFormat(parten);
// 设置日期的显示
select_month = wv_month.getCurrentItem() + 1;
select_day = wv_day.getCurrentItem() + 1;
select_year=wv_year.getCurrentItem()+start_year;
String aa = (wv_year.getCurrentItem()+start_year)+"-"+(decimal.format((wv_month.getCurrentItem() + 1))
+ "-" + decimal.format((wv_day.getCurrentItem() + 1)));
date_select.setText(aa); dialog.dismiss();
}
});
// 取消
btn_cancel.setOnClickListener(new OnClickListener() { @Override
public void onClick(View arg0) {
// TODO Auto-generated method stub
dialog.dismiss();
}
});
// 设置dialog的布局,并显示
dialog.setContentView(view);
dialog.show();
}
由这长段的源代码,我们可以得出这样的总结了:
①获取当前的日期,显示到相应的时间选择器中。
②利用大小月天数,对相应的大小月天数进行保存。
③添加相应的填充器,对月份滚轮,年分滚轮的数据进行了一系列的填充。
④并且根据月份,是否闰年等相关的条件, 对其天数的滚轮进行了填充。
⑤也是我重点要提的一个方法,对其移动后的时间滚轮所指向的天数进行调整,这是解决一个什么问题了,就是倘若滚动到3月31日时候,月份再次拨回四的时候,此时应该指向4月1日啊。这个就是onend方法所做的事情了。
综上所述,一个闹钟app就此ok了,其效果如下图:
揭破android中的闹钟app 二的更多相关文章
- 解剖android中的闹钟app 一
首先,看一看android市场上有哪些主流的闹钟app了,我们来进行一个简单的评测: 一.正点闹钟 这是一款源自金山技术的闹钟app,其主力创始团队都是来自于金山,其装机量,下载量都是排名第一.老样子 ...
- Android中对闹钟Alarm的事件处理
之前的博文一直在持续分享Phone相关的知识也算是知识笔记,但在工作中难免遇到其他模块的一些问题,因此在解决这些问题的时候顺手将这些知识记录并分享出来.有些知识在不知道的时候会觉得非常难,当了解之后便 ...
- Android中实现跨app之间数据的暴露与接收
例如一个小项目:实现单词本的添加单词等功能 功能:不同的方式实现跨app之间数据的暴露与接收 暴露端app:实现单词的添加(Word.Translate),增删改查: 接收端app:模糊查询,得到暴露 ...
- Android中的自定义控件(二)
案例四: 自定义开关 功能介绍:本案例实现的功能是创建一个自定义的开关,可以自行决定开关的背景.当滑动开关时,开关的滑块可跟随手指移动.当手指松开后,滑块根据开关的状态,滑到最右边或者滑到 ...
- Android中View绘制优化二一---- 使用<include />标签复用布局文件
本文原创, 转载请注明出处:http://blog.csdn.net/qinjuning 译二: 使用<include />标签复用布局文件 翻译地址:http://de ...
- Android中实现进入App之后检查网络状态
1,注册广播,一般使用静动态注册,即当程序退出的时候广播接受者就收不到消息使用方法context.registerReceiver()方法在MainActivity中的OnStart()方法中执行注册 ...
- Android中Intent具体解释(二)之使用Intent广播事件及Broadcast Receiver简单介绍
通过第一篇的解说,我们已经看到了怎样使用Intent来启动新的应用程序组件,可是实际上他们也能够使用sendBroadcast方法来在组件间匿名的广播消息. 作为一个系统级别的消息传递机制,Inten ...
- android中的简单animation(二)push up,push left,cross fade,hyperspace
animation_2.xml: <?xml version="1.0" encoding="utf-8"?> <LinearLayout x ...
- 关于Android中设置闹钟的相对比较完善的解决方案
我当时说承诺为大家写一个,一直没空,直到最近又有人跟我要,我决定抽时间写一个吧.确实设置闹钟是一个比较麻烦的东西.我在这里写的这个demo抽出来了封装了一个类库,大家直接调用其中的设置闹钟和取消闹钟的 ...
随机推荐
- 【转载】CMenu自绘---钩子---去除边框
使用默认的CMenu菜单类或者继承CMenu实现的菜单扩展类,在显示的时候最外层都会有边框出现,或者说是具有3D外观(菜单阴影不算),当改变菜单背景色或者需要加个边框线时就会看上去很不美观.看过很多菜 ...
- Xtreme9.0 - Light Gremlins 容斥
Xtreme9.0 - Light Gremlins 题目连接: https://www.hackerrank.com/contests/ieeextreme-challenges/challenge ...
- ios数据保存
- UVA 11732 - strcmp() Anyone?(Trie)
UVA 11732 - strcmp() Anyone? 题目链接 题意:给定一些字符串,要求两两比較,须要比較的总次数(注意.假设一个字符同样.实际上要还要和'\0'比一次,相当比2次) 思路:建T ...
- DG449 High Voltage Single SPDT Analog Switch in SOT23-8
DESCRIPTION The DG449 is a dual supply single-pole/double-throw (SPDT) switches. On resistance is 38 ...
- USB2.0 速度识别--区分低速-高速-全速
USB2.0是向下兼容USB1.X的,即USB2.0支持高速,全速,低速的USB设备 (HIGH-SPEED,FULL-SPEED,LOW-SPEED),而USB1.X不支持高速设备. 因此如果高速设 ...
- 8张图理解Java---importnew---programcreek
http://www.importnew.com/11725.html https://www.programcreek.com/2013/09/top-8-diagrams-for-understa ...
- ArcGIS Desktop水文计算
根据DEM数据,可以做流域.流向.等级河流划分. 网络资源的方位位置: , Click here to visit. 一.一些概念 二.水文分析工具集概念
- MORMOT的数据序列
MORMOT的数据序列 mormot服务器回复客户端通过Ctxt.OutContent属性. 此属性的类型是:SockString. // property OutContent: SockStr ...
- 错误:update 忘了加 where
职业生涯应该都犯过的错误,幸好是在开发库,生产环境的库真是要严格的进行权限管理和脚本执行流程规范.