· 這節,我們通過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了,其效果如下圖: