Android自定义日历控件

jopen 9年前

    /**        * 描述:自定义日历控件        * The Class CalendarView.        * @author LiuZiWei        * @date 2014-4-28        */        @SuppressLint("ViewConstructor")        public class CalendarView extends LinearLayout {                        /** The context. */            private Context context;                        /** The m linear layout header. */            private LinearLayout mLinearLayoutHeader = null;                        /** The m linear layout content. */            private LinearLayout mLinearLayoutContent = null;            /** The m calendar header. */            private CalendarHeader  mCalendarHeader = null;                        /** The width. */            private int width = 200;                                /** 星期头的行高. */            private int headerHeight = MY.PHONEWIDTH/7-10;                        //行高            /** The row height. */            private int rowHeight = MY.PHONEWIDTH/7-10;            //每个单元格的宽度            /** The cell width. */            private int cellWidth = MY.PHONEWIDTH/7;                        // 日期变量            /** The cal start date. */            public static Calendar calStartDate = Calendar.getInstance();                        /** The cal today. */            private Calendar calToday = Calendar.getInstance();                        /** The cal selected. */            private static Calendar calSelected = null;            //累计日期            /** The cal calendar. */            private Calendar calCalendar = Calendar.getInstance();                        /** The current month. */            private int currentMonth = 0;                        //本日历的第一个单元格的星期            /** The first day of week. */            private int firstDayOfWeek = Calendar.SUNDAY;            //今天            private int Teday;            private int ThisMonth;                        //得到需要特别显示的字的数据                                    private ArrayList<String> numberlist = new ArrayList<String>();                        //当前显示的单元格            /** The m calendar cells. */            private static ArrayList<CalendarCell> mCalendarCells = new ArrayList<CalendarCell>();                        /** The m on item click listener. */            private AbOnItemClickListener mOnItemClickListener;                        /**            * Instantiates a new ab grid view.            *            * @param context the context            */            public CalendarView(Context context,ArrayList<String> array) {                                this(context,array, null);                            }                                   /**            * Instantiates a new calendar view.            *            * @param context the context            * @param attrs the attrs            */            @SuppressWarnings("deprecation")            public CalendarView(Context context,ArrayList<String> array,AttributeSet attrs) {                super(context, attrs);                this.context = context;                this.numberlist=array;                        new LinearLayout.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT);                this.setOrientation(LinearLayout.VERTICAL);                this.setBackgroundColor(Color.rgb(255, 255, 255));                                WindowManager wManager = (WindowManager)context.getSystemService(Context.WINDOW_SERVICE);                       Display display = wManager.getDefaultDisplay();                     width = display.getWidth();                     display.getHeight();                                mLinearLayoutHeader = new LinearLayout(context);                mLinearLayoutHeader.setLayoutParams(new LayoutParams(width,headerHeight));                mLinearLayoutHeader.setOrientation(LinearLayout.VERTICAL);                mCalendarHeader = new CalendarHeader(context);                mCalendarHeader.setLayoutParams(new LayoutParams(width,headerHeight));                mLinearLayoutHeader.addView(mCalendarHeader,new LinearLayout.LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT));                addView(mLinearLayoutHeader);                                                mLinearLayoutContent = new LinearLayout(context);                mLinearLayoutContent.setOrientation(LinearLayout.VERTICAL);                addView(mLinearLayoutContent);                                cellWidth = (width-20)/7;                        //初始化选中今天                calSelected = Calendar.getInstance();                initRow();                initStartDateForMonth();                initCalendar();            }                        /**            * Inits the row.            */            public void initRow(){                mLinearLayoutContent.removeAllViews();                mCalendarCells.clear();                for (int iRow = 0; iRow <6; iRow++) {                    LinearLayout mLinearLayoutRow = new LinearLayout(context);                    mLinearLayoutRow.setLayoutParams(new LayoutParams(width,rowHeight));                    mLinearLayoutRow.setOrientation(LinearLayout.HORIZONTAL);                    for (int iDay = 0; iDay < 7; iDay++) {                        CalendarCell dayCell = new CalendarCell(context,(iRow*7)+iDay,cellWidth,rowHeight);                                dayCell.setOnItemClickListener(mOnDayCellClick);                                                mLinearLayoutRow.addView(dayCell);                        mCalendarCells.add(dayCell);                    }                    mLinearLayoutContent.addView(mLinearLayoutRow);                }            }                                    /**            * 描述:由于日历上的日期都是从周日开始的,计算第一个单元格的日期.            */            private void initStartDateForMonth() {                calStartDate.setTimeInMillis(calSelected.getTimeInMillis());                //获取当前的                currentMonth = calStartDate.get(Calendar.MONTH);                calStartDate.get(Calendar.YEAR);                                calStartDate.set(Calendar.DAY_OF_MONTH, 1);                calStartDate.set(Calendar.HOUR_OF_DAY, 0);                calStartDate.set(Calendar.MINUTE, 0);                calStartDate.set(Calendar.SECOND, 0);                                int iDay = 0;                int iStartDay = firstDayOfWeek;                                if (iStartDay == Calendar.MONDAY) {                    iDay = calStartDate.get(Calendar.DAY_OF_WEEK) - Calendar.MONDAY;                    if (iDay < 0)                        iDay = 6;                }                                if (iStartDay == Calendar.SUNDAY) {                    iDay = calStartDate.get(Calendar.DAY_OF_WEEK) - Calendar.SUNDAY;                    if (iDay < 0)                        iDay = 6;                }                                calStartDate.add(Calendar.DAY_OF_WEEK, -iDay);            }                        /**            * 描述:更新日历.            */            private void updateCalendar() {                final boolean bIsSelection = (calSelected.getTimeInMillis() != 0);                final int iSelectedYear = calSelected.get(Calendar.YEAR);                final int iSelectedMonth = calSelected.get(Calendar.MONTH);                final int iSelectedDay = calSelected.get(Calendar.DAY_OF_MONTH);                                boolean isThisMonth  = false;                //今天在当前月,则去掉默认选中的1号                if (calToday.get(Calendar.YEAR) == iSelectedYear) {                    if (calToday.get(Calendar.MONTH) == iSelectedMonth) {                        isThisMonth = true;                    }                }                                calCalendar.setTimeInMillis(calStartDate.getTimeInMillis());                for (int i = 0; i < mCalendarCells.size(); i++) {                    CalendarCell dayCell = mCalendarCells.get(i);                    //                    final int iYear = calCalendar.get(Calendar.YEAR);                    final int iMonth = calCalendar.get(Calendar.MONTH);                    final int iDay = calCalendar.get(Calendar.DAY_OF_MONTH);                    final int iDayOfWeek = calCalendar.get(Calendar.DAY_OF_WEEK);                                                            boolean isOrage=false;                    boolean isLatDay=false;                    // 判断是否当天                    boolean bToday = false;                    // 是否被选中                    boolean bSelected = false;                    // check holiday                    boolean bHoliday = false;                    // 是否有记录                    boolean hasRecord = false;                                                            if (calToday.get(Calendar.YEAR) == iYear) {                        if (calToday.get(Calendar.MONTH) == iMonth) {                            ThisMonth=iMonth;                            if (calToday.get(Calendar.DAY_OF_MONTH) == iDay) {                                Teday=iDay;                                bToday = true;                            }else if (calToday.get(Calendar.DAY_OF_MONTH)>iDay) {                                //判断是不是过去的日期                                isLatDay = true;                            }                        }                    }                                        //判断应该变成橘色的数据                    if(null!=numberlist){                        if (calToday.get(Calendar.YEAR) == iYear) {                            if (calToday.get(Calendar.MONTH) == iMonth) {                                for(int j=0;j<numberlist.size();j++){                                                                        if(Integer.parseInt(numberlist.get(j))==iDay){                                                                            isOrage=true;                                    }                                }                                                    }                        }                    }                                                                                if ((iDayOfWeek == Calendar.SATURDAY) || (iDayOfWeek == Calendar.SUNDAY)){                                                bHoliday = true;                                            }                    if ((iMonth == Calendar.JANUARY) && (iDay == 1)){                                                bHoliday = true;                                            }                            if (bIsSelection){                        if ((iSelectedDay == iDay) && (iSelectedMonth == iMonth) && (iSelectedYear == iYear)) {                            bSelected = true;                        }else{                            bSelected = false;                        }                    }                                        if(iDay==1 && isThisMonth){                        bSelected = false;                    }                            dayCell.setThisCellDate(iYear, iMonth, iDay, bToday,bSelected, bHoliday,currentMonth, isLatDay,isOrage,hasRecord);                            calCalendar.add(Calendar.DAY_OF_MONTH, 1);                }                                invalidate();            }                        /**            * 描述:更新日历.            */            private void initCalendar() {                final boolean bIsSelection = (calSelected.getTimeInMillis() != 0);                final int iSelectedYear = calSelected.get(Calendar.YEAR);                final int iSelectedMonth = calSelected.get(Calendar.MONTH);                final int iSelectedDay = calSelected.get(Calendar.DAY_OF_MONTH);                                calCalendar.setTimeInMillis(calStartDate.getTimeInMillis());                        for (int i = 0; i < mCalendarCells.size(); i++) {                    CalendarCell dayCell = mCalendarCells.get(i);                    //                    final int iYear = calCalendar.get(Calendar.YEAR);                    final int iMonth = calCalendar.get(Calendar.MONTH);                    final int iDay = calCalendar.get(Calendar.DAY_OF_MONTH);                    final int iDayOfWeek = calCalendar.get(Calendar.DAY_OF_WEEK);                                        boolean isOrage=false;                    boolean isLatDay=false;                    // 判断是否当天                    boolean bToday = false;                    // 是否被选中                    boolean bSelected = false;                    // check holiday                    boolean bHoliday = false;                                        if (calToday.get(Calendar.YEAR) == iYear) {                        if (calToday.get(Calendar.MONTH) == iMonth) {                            ThisMonth=iMonth;                            if (calToday.get(Calendar.DAY_OF_MONTH) == iDay) {                                Teday=iDay;                                bToday = true;                            }else if (calToday.get(Calendar.DAY_OF_MONTH)>iDay) {                                isLatDay=true;                            }                        }                    }                                                                            //判断应该变成橘色的数据                    if(null!=numberlist){                        if (calToday.get(Calendar.YEAR) == iYear) {                            if (calToday.get(Calendar.MONTH) == iMonth) {                                for(int j=0;j<numberlist.size();j++){                                                                        if(Integer.parseInt(numberlist.get(j))==iDay){                                                                            isOrage=true;                                    }                                }                                                    }                        }                    }                                        if ((iDayOfWeek == Calendar.SATURDAY) || (iDayOfWeek == Calendar.SUNDAY)){                        bHoliday = true;                    }                    if ((iMonth == Calendar.JANUARY) && (iDay == 1)){                        bHoliday = true;                    }                                        if (bIsSelection){                        if ((iSelectedDay == iDay) && (iSelectedMonth == iMonth) && (iSelectedYear == iYear)) {                            bSelected = true;                        }else{                            bSelected = false;                        }                    }                                                dayCell.setThisCellDate(iYear, iMonth, iDay, bToday,bSelected, bHoliday,currentMonth,isLatDay,isOrage,false);                            calCalendar.add(Calendar.DAY_OF_MONTH, 1);                }                                invalidate();            }                                /**            * Sets the on item click listener.            *            * @param mAbOnItemClickListener the new on item click listener            */            public void setOnItemClickListener(AbOnItemClickListener mAbOnItemClickListener) {                this.mOnItemClickListener = mAbOnItemClickListener;            }                    /**            * Sets the header height.            *            * @param height the new header height            */            public void setHeaderHeight(int height) {                headerHeight = height;                mLinearLayoutHeader.removeAllViews();                mCalendarHeader.setLayoutParams(new LayoutParams(width,headerHeight));                mLinearLayoutHeader.addView(mCalendarHeader,new LinearLayout.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));                this.invalidate();                            }                        /**            * Sets the header text size.            *            * @param size the new header text size            */            public void setHeaderTextSize(int size) {                mCalendarHeader.setTextSize(size);                this.invalidate();            }                    /**            * Rebuild calendar.            *            * @param calendar the calendar            */            public void rebuildCalendar(Calendar calendar) {                //初始化选中1号                calSelected.setTimeInMillis(calendar.getTimeInMillis());                initRow();                initStartDateForMonth();                updateCalendar();            }                       /** 点击日历,触发事件. */            private AbOnItemClickListener mOnDayCellClick = new AbOnItemClickListener(){                        @Override                public void onClick(int position) {                    CalendarCell mCalendarCell = mCalendarCells.get(position);                    //如果为当月的大于等于当天的,则可以点击否则不可以                    if( (mCalendarCell.isActiveMonth() && mCalendarCell.getiDateMonth()==ThisMonth && mCalendarCell.getiDateDay()>Teday) || (mCalendarCell.isActiveMonth()  && mCalendarCell.getiDateMonth()!=ThisMonth)){                        calSelected.setTimeInMillis(mCalendarCell.getThisCellDate().getTimeInMillis());                                for(int i=0;i<mCalendarCells.size();i++){                            CalendarCell mCalendarCellOther = mCalendarCells.get(i);                                                        mCalendarCellOther.setSelected(false);                        }                        mCalendarCell.setSelected(true);                        if(mOnItemClickListener!=null){                            mOnItemClickListener.onClick(position);                        }                    }                }                            };                        /**             * 描述:设置标题背景.             *             * @param resid the new header background resource             */            public void setHeaderBackgroundResource(int resid){                                mCalendarHeader.setHeaderBackgroundResource(resid);                            }                        public void setHeaderBackgroundColor(int resid){                                mCalendarHeader.setHeaderBackgroundColor(resid);                            }                        /**             * 描述:根据索引获取选择的日期.             *             * @param position the position             * @return the str date at position             */            public static String getStrDateAtPosition(int position){                CalendarCell mCalendarCell = mCalendarCells.get(position);                Calendar calendar = mCalendarCell.getThisCellDate();                int year = calendar.get(Calendar.YEAR);                int month = calendar.get(Calendar.MONTH)+1;                int day = calendar.get(Calendar.DATE);                final int iWeek=calSelected.get(Calendar.DAY_OF_WEEK)-1;                String week;                switch (iWeek) {                case 1:                    week="星期一";                    break;                case 2:                    week="星期二";                    break;                case 3:                    week="星期三";                    break;                case 4:                    week="星期四";                    break;                case 5:                    week="星期五";                    break;                case 6:                    week="星期六";                    break;                                default:                    week="星期日";                    break;                }                return year+"-"+month+"-"+day+"-"+week;                    }                        /**             * 描述:获取这个日历的总日期数.             *             * @return the calendar cell size             */            public int getCalendarCellSize(){                return mCalendarCells.size();            }                    /**            * 描述:获取当前日历的所有条目.            *            * @return the calendar cells            */            public ArrayList<CalendarCell> getCalendarCells() {                                return mCalendarCells;                            }                    /**            * 描述:获取选中的日期,默认为今天.            *            * @return the cal selected            */            public String getCalSelected() {                final int iYear = calSelected.get(Calendar.YEAR);                final int iMonth = calSelected.get(Calendar.MONTH)+1;                final int iDay = calSelected.get(Calendar.DAY_OF_MONTH);                final int iWeek=calSelected.get(Calendar.DAY_OF_WEEK)-1;                String week;                switch (iWeek) {                case 1:                    week="星期一";                    break;                case 2:                    week="星期二";                    break;                case 3:                    week="星期三";                    break;                case 4:                    week="星期四";                    break;                case 5:                    week="星期五";                    break;                case 6:                    week="星期六";                    break;                                default:                    week="星期日";                    break;                }                return iYear+"-"+iMonth+"-"+iDay+"-"+week;            }                            }  
来自:http://blog.csdn.net/wangchunshun/article/details/32311497