MyCalendar 開發日誌 2
上周花了不少時間,總算把日曆的demo程序(https://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中修改,但是可惜都成功不了。先放著吧,回頭再看看有沒有別的解決辦法。
最後更新:2017-04-03 12:56:21