·  这节,我们通过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 二的更多相关文章

  1. 解剖android中的闹钟app 一

    首先,看一看android市场上有哪些主流的闹钟app了,我们来进行一个简单的评测: 一.正点闹钟 这是一款源自金山技术的闹钟app,其主力创始团队都是来自于金山,其装机量,下载量都是排名第一.老样子 ...

  2. Android中对闹钟Alarm的事件处理

    之前的博文一直在持续分享Phone相关的知识也算是知识笔记,但在工作中难免遇到其他模块的一些问题,因此在解决这些问题的时候顺手将这些知识记录并分享出来.有些知识在不知道的时候会觉得非常难,当了解之后便 ...

  3. Android中实现跨app之间数据的暴露与接收

    例如一个小项目:实现单词本的添加单词等功能 功能:不同的方式实现跨app之间数据的暴露与接收 暴露端app:实现单词的添加(Word.Translate),增删改查: 接收端app:模糊查询,得到暴露 ...

  4. Android中的自定义控件(二)

    案例四: 自定义开关       功能介绍:本案例实现的功能是创建一个自定义的开关,可以自行决定开关的背景.当滑动开关时,开关的滑块可跟随手指移动.当手指松开后,滑块根据开关的状态,滑到最右边或者滑到 ...

  5. Android中View绘制优化二一---- 使用<include />标签复用布局文件

    本文原创, 转载请注明出处:http://blog.csdn.net/qinjuning   译二:   使用<include />标签复用布局文件      翻译地址:http://de ...

  6. Android中实现进入App之后检查网络状态

    1,注册广播,一般使用静动态注册,即当程序退出的时候广播接受者就收不到消息使用方法context.registerReceiver()方法在MainActivity中的OnStart()方法中执行注册 ...

  7. Android中Intent具体解释(二)之使用Intent广播事件及Broadcast Receiver简单介绍

    通过第一篇的解说,我们已经看到了怎样使用Intent来启动新的应用程序组件,可是实际上他们也能够使用sendBroadcast方法来在组件间匿名的广播消息. 作为一个系统级别的消息传递机制,Inten ...

  8. android中的简单animation(二)push up,push left,cross fade,hyperspace

    animation_2.xml: <?xml version="1.0" encoding="utf-8"?> <LinearLayout x ...

  9. 关于Android中设置闹钟的相对比较完善的解决方案

    我当时说承诺为大家写一个,一直没空,直到最近又有人跟我要,我决定抽时间写一个吧.确实设置闹钟是一个比较麻烦的东西.我在这里写的这个demo抽出来了封装了一个类库,大家直接调用其中的设置闹钟和取消闹钟的 ...

随机推荐

  1. BZOJ3355 : [Usaco2004 Jan]有序奶牛

    对于一条边x->y,若去掉之后x不能到达y,那么它是必需的. 首先拓扑排序求出拓扑序,然后按照终点拓扑序为第一关键字,起点拓扑序为第二关键字从小到大加边. 对于每个点,维护一个bitset,表示 ...

  2. 吴恩达-coursera-机器学习-week5

    九.神经网络的学习(Neural Networks: Learning) 9.1 代价函数 9.2 反向传播算法 9.3 反向传播算法的直观理解 9.4 实现注意:展开参数 9.5 梯度检验 9.6 ...

  3. 吴恩达-coursera-机器学习-week2

    四.多变量线性回归(Linear Regression with Multiple Variables) 4.1 多维特征 4.2 多变量梯度下降 4.3 梯度下降法实践1-特征缩放 4.4 梯度下降 ...

  4. HDU 5909 Tree Cutting 动态规划 快速沃尔什变换

    Tree Cutting 题目连接: http://acm.hdu.edu.cn/showproblem.php?pid=5909 Description Byteasar has a tree T ...

  5. MikroTik RouterOS虚拟机/实体机安装方法

    一.设置光驱 二.安装RouerOS 按a全选,按i安装,q退出,空格可以选取或取消选取.这里是选择你要安装的组件. 是否要保存原有配置:是否要提交.一路y. 安装好之后按回车重启:之后为这个界面,安 ...

  6. vue首屏加载优化

    库使用情况 vue vue-router axios muse-ui material-icons vue-baidu-map 未优化前 首先我们在正常情况下build 优化 1. 按需加载 当前流行 ...

  7. 基於tiny4412的Linux內核移植 --- 实例学习中断背后的知识(2)

    作者:彭东林 邮箱:pengdonglin137@163.com QQ:405728433 平台 tiny4412 ADK Linux-4.9 概述 前面一篇博文基於tiny4412的Linux內核移 ...

  8. ASP.NET Identity系列01,揭开神秘面纱

    早在2005年的时候,微软随着ASP.NET 推出了membership机制,十年磨一剑,如今的ASP.NET Identity是否足够强大,一起来体会. 在VS2013下新建项目,选择"A ...

  9. 多个按钮触发同一个Bootstrap自适应模态窗口

    在项目中可能会面对这样的一个场景: 界面上有多个按钮,我们希望点击这些按钮弹出同一个模态窗口,但希望模态窗口的内容是动态生成的,即,点击每个按钮弹出的模态窗口内容不同. 通常情况下,一个按钮对应一个模 ...

  10. ISO 8601: Delphi way to convert XML date and time to TDateTime and back (via: Stack Overflow)

    Recently I needed a way of concerting back and forth ISO 8601 DateTime values used in XML from Delph ...