android 日曆選擇器(酒店專用)
阿新 • • 發佈:2019-01-10
日曆選擇器
由於公司需求,參看了各個平臺的酒店日曆選擇功能,手動寫了一個,就當記錄下,程式碼邏輯可能還需要再去優化下,各位小夥伴沒思路的可以參考下。。接下來正題。
看下實現後效果圖吧。。
佈局上是RecyclerView巢狀RecyclerView,上面2018年月9月是通過自定義RecyclerView.ItemDecoration繪製,程式碼下面地址有,這裡就不解說自定義RecyclerView.ItemDecoration了。。。
((DefaultItemAnimator) mBinding.rv.getItemAnimator()).setSupportsChangeAnimations(false); //當前日期轉date SimpleDateFormat ymd_sdf=new SimpleDateFormat("yyyy-MM-dd"); try { if(currentDate==null){ new Throwable("please set one start time"); return; } mSetDate = ymd_sdf.parse(currentDate); } catch (ParseException e) { e.printStackTrace(); } //修改日曆物件的日期 Calendar c = Calendar.getInstance(); c.setTime(mSetDate); //獲取月份 月份是從0開始需要+1 int firstM= c.get(Calendar.MONTH)+1; //日期 int days=c.get(Calendar.DATE); //周幾 int week=c.get(Calendar.DAY_OF_WEEK); //獲取當前這個月最大天數 int maxDys=c.getActualMaximum(Calendar.DAY_OF_MONTH); int startDate=0; //日 一 二 三 四 五 六 //- - 當前 //需要求上週末的日期(週末到週一的日期)填補 if("1".equals(week+"")){ //今天是否週末 startDate=days; }else { //獲取上週末 startDate= Integer.parseInt(CalendarUtil.getPreviousWeekSundayByDate(ymd_sdf.format(mSetDate)).split("-")[2]); } DateInfo info = new DateInfo(); List<DayInfo> dayList=new ArrayList<>(); info.setDate(c.get(Calendar.YEAR)+ "年" + firstM + "月"); //根據週末日期開始計算到結尾日期的天數 //當小於當前日期時,是不可選,setEnable(false) //如果上週末是大於當前的,說明上週末是上個月的 //如何判斷呢,1,當前日期小於週末則是上個月 2,其他情況是當前日期肯定會大於週末 if(days<startDate){ //計算上個月在本週日曆的日期 //獲取上月最後一天的日期 String previousMonthLastDate=CalendarUtil.getPreviousMonthEndByDate(ymd_sdf.format(mSetDate)); int previousMonthLastDay= Integer.parseInt(previousMonthLastDate.split("-")[2]); LogUtil.debugE("previousMonthLastDay",previousMonthLastDay+""); //從上個月週日日期算起,到上個月最後一天的日期 for (int i=startDate;i<=previousMonthLastDay;i++){ DayInfo dayInfo=new DayInfo() ; dayInfo.setName(i+""); dayInfo.setEnable(false); dayInfo.setDate(previousMonthLastDate.split("-")[0]+"-"+previousMonthLastDate.split("-")[1]); dayList.add(dayInfo); } //計算完後,迴歸為1號,計算當前這個月日期 startDate=1; } //計算當前月的天數 for (int i=startDate ; i<=maxDys;i++){ DayInfo dayInfo=new DayInfo() ; dayInfo.setName(i+""); dayInfo.setDate(c.get(Calendar.YEAR)+"-"+(c.get(Calendar.MONTH)+1)+"-"+i); int c_year= Integer.parseInt(currentDate.split("-")[0]); int c_month= Integer.parseInt(currentDate.split("-")[1]); int c_day= Integer.parseInt(currentDate.split("-")[2]); if(c_year==c.get(Calendar.YEAR) && c_month==(c.get(Calendar.MONTH)+1) && c_day==i){ dayInfo.setName("今天"); c_stratChildPosition=dayList.size(); } if(c_year==c.get(Calendar.YEAR) && c_month==(c.get(Calendar.MONTH)+1) && c_day+1==i){ dayInfo.setName("明天"); } if(i<days){ dayInfo.setEnable(false); }else { dayInfo.setEnable(true); } dayList.add(dayInfo); } info.setList(dayList); mList.add(info);
以上是計算當前月的日曆表,currentDate是從伺服器拉取的時間,這裡我們可以模仿下,設定一個日期yyyy-MM-dd,獲取Calendar物件,設定時間為currentDate。以週日-週六為標準。首先理清下 ,計算第一個週末是上個月的週日還是本月的週日,如果是上個月週末,我們需要獲取上個週日的日期和上個月最後一個月的最後一天日期,計算相差的日期。如果第一個週日是本月,則當前日期肯定大於上週日的日期。
//獲取下3個月的資料 for (int i=1 ;i<8;i++){ //當前月份迴圈加1 c.add(Calendar.MONTH,01); DateInfo nextInfo = new DateInfo(); List<DayInfo> nextdayList=new ArrayList<>(); int maxDays=c.getActualMaximum(Calendar.DAY_OF_MONTH); nextInfo.setDate(c.get(Calendar.YEAR)+ "年" + (c.get(Calendar.MONTH)+1) + "月"); //周幾 int weeks=CalendarUtil.getWeekNoFormat(c.get(Calendar.YEAR)+"-"+(c.get(Calendar.MONTH)+1)+"-01")-1; LogUtil.debugE("---",weeks+""); //根據該月的第一天,星期幾,填充上個月的空白日期 for (int t=0;t<weeks;t++){ DayInfo dayInfo=new DayInfo() ; dayInfo.setName(""); dayInfo.setEnable(false); dayInfo.setDate(""); nextdayList.add(dayInfo); } //該月的所有日期 for (int j=0;j<maxDays;j++){ DayInfo dayInfo=new DayInfo() ; dayInfo.setName((j+1)+""); dayInfo.setEnable(true); dayInfo.setDate(c.get(Calendar.YEAR)+"-"+(c.get(Calendar.MONTH)+1)+"-"+(j+1)); nextdayList.add(dayInfo); } nextInfo.setList(nextdayList); mList.add(nextInfo); LogUtil.debugE("--",c.getActualMaximum(Calendar.DAY_OF_MONTH)+"-"+c.get(Calendar.YEAR)+"-"+c.get(Calendar.MONTH)); }
計算後3個月的日曆日期,這部分好算,根據Calendar計算每個月的最大天數。獲取每個月的第一天的日期,判斷是否是週末,是週末,我們直接new Dayinfo新增,否則的話,我們需要根據第一天計算出周幾,往後退到週日的日期,新增空資料。
//設定日曆標明今天明天 public void setDefaultSelect(){ if(c_stratChildPosition==-1)return; String date=mList.get(0).getList().get(c_stratChildPosition).getDate(); LogUtil.debugE("zuixina---",date); SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd"); Date curDate=null; try { curDate=sdf.parse(FormatDate(date)); } catch (ParseException e) { e.printStackTrace(); } if(curDate==null)return; Calendar calendar= Calendar.getInstance(); calendar.setTime(curDate); calendar.add(Calendar.DATE,1); int year= Integer.parseInt(date.split("-")[0]); int month= Integer.parseInt(date.split("-")[1]); if(year==calendar.get(Calendar.YEAR) && month==calendar.get(Calendar.MONTH)+1 && c_stratChildPosition<mList.get(0).getList().size()-1){ setInit(0,c_stratChildPosition,0,c_stratChildPosition+1); }else { for (int i=0;i<mList.get(1).getList().size();i++){ if(!TextUtils.isEmpty(mList.get(1).getList().get(i).getDate())){ setInit(0,c_stratChildPosition,1,i); break; } } } LogUtil.debugE("zusixin---",calendar.get(Calendar.YEAR)+"-"+calendar.get(Calendar.MONTH)+"-"+calendar.get(Calendar.DATE)); // }
該方法根據c_stratChildPosition,這個是currentDate日期在陣列列表的位置標識,根據該標識去初始化預設的“今天”“明天”。
大概的計算也就這幾個地方,其他的基本都是重新整理邏輯,程式碼裡註釋也比較詳細。可以參考程式碼來理解。。。。寫的不好請多多諒解。。。謝謝各位。