android 日曆選擇器(酒店專用)

日曆選擇器

由於公司需求,參看了各個平臺的酒店日曆選擇功能,手動寫了一個,就當記錄下,代碼邏輯可能還需要再去優化下,各位小夥伴沒思路的可以參考下。。接下來正題。


看下實現後效果圖吧。。


佈局上是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日期在數組列表的位置標識,根據該標識去初始化默認的“今天”“明天”。


大概的計算也就這幾個地方,其他的基本都是刷新邏輯,代碼裏註釋也比較詳細。可以參考代碼來理解。。。。寫的不好請多多諒解。。。謝謝各位。

gitlub地址

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章