- 1、本文档共14页,可阅读全部内容。
- 2、有哪些信誉好的足球投注网站(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。
- 3、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载。
- 4、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
查看更多
Android自定义View(CustomCalendar-定制日历控件)
Android自定义View(CustomCalendar-定制日历控件)
如图,上部分是自定义日历的效果图,下面是系统自带CalendarView的效果,这两个控件的相关功能需求元素图上都有标注。系统自带的日历控件能够左右滑动切换月份,效果还是挺酷的(这是我在自定义控件完毕之后才发现的),结果就后悔了,这么酷干嘛还要自定义啊?
??自定义当然不是为了装逼呐,请认真看需求,我们需要在日期下面显示任务完成情况,当日被切换之后需要标注为灰色圆圈背景,这些都是自带日历控件不可达到的,当然,我们也可以继承系统CalendarView然后试着修改;那为什么不选择开源的日历控件呢?如果我们不会自定义控件或者时间很紧,开源的当然是首选,谁叫我闲的慌,开源的控件也会有些问题,有的可能不够完善很多bug,比较完善的可能内容太多,如果要抽取有用的内容还是需要花一定时间,如果整个库工程都弄过来会造成大量的代码冗余。另外一点很重要,任务情况需要从服务器上获取,当切换日期之后,日历控件下方要显示那天的任务详情(可能需要请求数据),这么多问题如果去修改开源库工程工作量不一定比自定义小。综上,还是自定义更适合我,整个日历控件500多行代码就搞定(包括注释、接口、各种变量),后面如果项目需求有变动,改动起来也是so easy! 当然,日常开发中,自带控件能搞定的尽量就用系统自带的。下面我们一起看看这个控件是怎样实现的。
分析
怎样自定义这个日历控件呢?可能我们第一反应是GridView+组合控件的方式,GridView用来展示下面日期部分,这种方式实现起来相对比较容易,但是核心的内容(获取某月的天数、具体展示在什么位置)还是得自己做,这种方式代码量也不少,另外这样做也会加大系统性能开销,GridView中同时显示30来个item,item里面还嵌套子控件,之前我们讲控件填充、测量时讲过尽量减少布局的嵌套,这样会造成过多的遍历,一不小心又装逼了,现在的手机那么牛逼,这么点工作量跟我谈什么性能?
??第二种就是通过自定义View完全绘制出来,只需要一个类搞定。其实绘制很简单,拿到一个画笔(Paint),我们就能画天画地画美女,爱画什么画什么,不需要有品位、不需要艺术功底,比起拿2B铅笔作画简单多了。
??如果要绘制出这个控件,我们首先要得到某个月的所有天数(从1号开始….)、1号是星期几(从什么位置开始展示),有了这两个数据,我们就能得到第一行从哪里开始绘制,能绘制多少天,最后一行能绘制多少天,其他中间的都是绘制7天;接下来需要绘制当前日期和被选中日期的背景,其实就是在绘制日期时先判断下日期是不是当前日期,如果是就给他先画一个背景,被选择的也是一样。我们先看看获取日期的算法:
/**设置月份*/
private void setMonth(String Month){
//设置的月份(2017年01月)
month = str2Date(Month);
Calendar calendar = Calendar.getInstance();
calendar.setTime(new Date());
//获取今天是多少号
currentDay = calendar.get(Calendar.DAY_OF_MONTH);
Date cM = str2Date(getMonthStr(new Date()));
//判断是否为当月
if(cM.getTime() == month.getTime()){
isCurrentMonth = true;
selectDay = currentDay;//当月默认选中当前日
}else{
isCurrentMonth = false;
selectDay = 0;
}
Log.d(TAG, 设置月份:+month+ 今天+currentDay+号, 是否为当前月:+isCurrentMonth);
calendar.setTime(month);
dayOfMonth = calendar.getActualMaximum(Calendar.DAY_OF_MONTH);
//第一行1号显示在什么位置(星期几)
firstIndex = calendar.get(Calendar.DAY_OF_WEEK)-1;
lineNum = 1;
//第一行能展示的天数
firstLineNum = 7-firstIndex;
lastLineNum = 0;
int she
文档评论(0)