上周花了不少时间,总算把日历的demo程序(http://blog.csdn.net/h7870181/article/details/8960478)弄清楚了。
关于画边框和数字以及背景的几个函数就不想写列出来,都是很简单的几个函数。重点写一下处理日期计算的函数。calulateDate()。
这个函数的目的是计算当前页面中42个日期的具体排列。42个日期很容易得出,看下自己电脑以及手机上的日历,都是6行7列的一个排列。因为有时候一个月的第一天会出现在周日,而31天的话,5行是不够使的,所以是6行7列。这就需要几件事情需要处理:
1. 判断当月的第一天在日历中的位置;
2. 填充上个月的最后几天;
3. 填充下个月的前几天。
这个思路清楚了以后,再看程序就不难理解了。
private void calculateDate() { // Confirm the position of the first day in current month calendar.setTime(curDate); calendar.set(Calendar.DAY_OF_MONTH, 1);// set the index to the first day // of current month int dayInWeek = calendar.get(Calendar.DAY_OF_WEEK);// Return the first // day of this month // is which day in a // week, Sunday is 1 // and Saturday is 7 Log.d(TAG, "day in week:" + dayInWeek); int monthStart = dayInWeek; if (monthStart == 1) { monthStart = 8; } monthStart -= 1; // 以星期一位開頭就-2,以星期天為开头就-1 curStartIndex = monthStart; date[monthStart] = 1;// find the position of 1st // Fill the days in last month if (monthStart > 0) { calendar.set(Calendar.DAY_OF_MONTH, 0);// Set the index to the last // day of last month int dayInmonth = calendar.get(Calendar.DAY_OF_MONTH);// Because it's // the last // day for (int i = monthStart - 1; i >= 0; i--) { date[i] = dayInmonth; dayInmonth--; } calendar.set(Calendar.DAY_OF_MONTH, date[0]); // record the first // day in this page } showFirstDate = calendar.getTime(); // this month calendar.setTime(curDate); calendar.add(Calendar.MONTH, 1);// because we have to get the number of // the day in current day, so we need to // add one month then go back calendar.set(Calendar.DAY_OF_MONTH, 0); // Log.d(TAG, "m:" + calendar.get(Calendar.MONTH) + " d:" + // calendar.get(Calendar.DAY_OF_MONTH)); int monthDay = calendar.get(Calendar.DAY_OF_MONTH);// get the number of // day in this // month. for (int i = 1; i < monthDay; i++) { date[monthStart + i] = i + 1; } curEndIndex = monthStart + monthDay;// last day in this month // next month for (int i = monthStart + monthDay; i < 42; i++) { date[i] = i - (monthStart + monthDay) + 1; } if (curEndIndex < 42) { // 显示了下一月的 // calendar.add(Calendar.DAY_OF_MONTH, 1); } calendar.set(Calendar.DAY_OF_MONTH, date[41]); showLastDate = calendar.getTime(); }正如我自己写的注释一样,逐行解释下代码的意思吧:
setTime(curDate),将日历设置成当前月份,这样才能在下一行set(Calendar.DAY_OF_MONTH, 1)函数中将index设置到当月的第一天,
然后再利用get(calendar.DAY_OF_WEEK)函数就可以返回这个月的第一天是当月中的星期几了。注意周日返回1,周六是7。
接下来因为很多日历有自己的模式,比如有的把周日当做一周的第一天,有的把周一当做第一天。所以monthStart -=1(or 2)来把当前的模式设置成自己想要的格式。
举个例子更容易理解。4月1号是周二,monthStart得到的结果是3,因为我是把周日设为每周的第一天,所以,减1后monthStart是2,所以Date[2] =1。 也就是当月矩阵的第3天是1号。(数组从0开始)。
好了,第一天找到了,接下来就开始把上个月的最后几天填进去了。那如何确定上个月有几天呢?
一样的方法。
set(Calendar.DAY_OF_MONTH, 0),经过debug查看dayInmonth的值,我感觉把set函数的第二个参数设置成0的意思是将index回滚到上个月的最后一天,然后再调用get函数当然得到的结果就是上个月的天数了。
接下来的for循环就不用多说了吧。
然后填充当月的数字:
这里为了得到本月总共有多少天,需要先add(calendar.MONTH,1),将index设置到下个月,然后再set(calendar.DAY_OF_MONTH,0)回滚到上个月(也就是当月)的最后一天,然后再get一下,就得到了这个月的天数(30?31?29?28?),然后知道了这个月有多少天,有知道了第一天的位置,很容易填充了,for循环就搞定了。
然后同样的方法,来把下个月的若干天也填充到数组中去。
核心的算法就是这个函数。
今天再次尝试了下全屏的方法,之前在网上看有两种方法:
方法1:
使用xml的方法,在该项目的AndroidManifest.xml文件中,在需要全屏的Activity元素中添加属性
android:theme="@android:style/Theme.NoTitleBar.Fullscreen"
这样就可以实现这个Activity的全屏显示,如果只是不要标题栏,即需要保留系统自带的任务栏的话,则使用
android:theme="@android:style/Theme.NoTitleBar"
这样的好处是可以不用在代码中进行修改
方法2:
即使用代码进行修改
在Activity 的OnCreat函数中加入下面的代码:
- requestWindowFeature(Window.FEATURE_NO_TITLE);
- getWindow().setFlags(WindowManager.LayoutParams. FLAG_FULLSCREEN ,WindowManager.LayoutParams. FLAG_FULLSCREEN);
使用代码可以动态使该Activity进行全屏,如可实现屏幕双击后进行全屏等
实际开发过程中,我使用修改xml的方法一直不行,每次在虚拟机上都运行不起来,然后尝试了一下在代码中修改,成功了,但是代码一定要在 setContentView(R.layout.activity_main_page) 之前,否则还是会报错。另外用代码的方法还有个不好的地方是刚开始的时候,上端的标题栏会闪一块黑色,然后过1秒才会变成全屏的。所以一直想尝试在XML中修改,但是可惜都成功不了。先放着吧,回头再看看有没有别的解决办法。