Android自定義日歷控件

jopen 10年前發布 | 27K 次閱讀 Android Android開發 移動開發

    /**

 * 描述:自定義日歷控件 
 * 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;  
    }  


}  </pre>來自:http://blog.csdn.net/wangchunshun/article/details/32311497<br />
 本文由用戶 jopen 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!