效果:

android自定义日历类


自定义属性:

[html] view plain copy
  1. <declare-styleable name="Calendar">  
  2.         <attr name="hpadding" format="float"></attr>  
  3.         <attr name="wpadding" format="float"></attr>  
  4.         <attr name="downcolor" format="color"></attr>  
  5.         <attr name="bordercolor" format="color"></attr>  
  6.         <attr name="weekcolor" format="color"></attr>  
  7.   
  8.         <attr name="monthbg1color" format="color"></attr>  
  9.         <attr name="monthbg1fill" format="boolean"></attr>  
  10.   
  11.         <attr name="monthbg2color" format="color"></attr>  
  12.         <attr name="monthbg2fill" format="boolean"></attr>  
  13.   
  14.         <attr name="todaycolor" format="color"></attr>  
  15.         <attr name="normalcolor" format="color"></attr>  
  16.         <attr name="othermonthcolor" format="color"></attr>  
  17.         <attr name="weekscale" format="float"></attr>  
  18.         <attr name="datescale" format="float"></attr>  
  19.         <attr name="ischinese" format="boolean"></attr>  
  20.         <attr name="isbold" format="boolean"></attr>  
  21.         <attr name="buttondistance" format="float"></attr>  
  22.   
  23.     </declare-styleable>  


因为自定义的属性,比较多配合下面几个图来说一下

android自定义日历类android自定义日历类android自定义日历类android自定义日历类


属性描述:

属性名称 属性描述 备注
hpadding 日历与上下的间距 默认为0
wpadding 日历与左右的间距 默认为0
buttondistance 按钮与左右的间距 默认为0
monthbg1color 背景1的颜色 默认为0x00000000
monthbg1fill 背景1是否全部填充 默认为false
monthbg2color 背景2的颜色 默认为0x00000000
monthbg2color 背景2是否全部填充 默认为false
bordercolor 边框的颜色 默认为0x00000000
todaycolor 今天日期的颜色 默认为0xFFFF0000
normalcolor 当前月的日期的颜色(注意,是指日历而不是现实中的) 默认为0xFF000000
othermonthcolor 其他月份的日期的颜色 默认为0xFFCCCCCC
isbold 星期文本与日期文本是否加粗 默认为false
weekscale 星期文本的缩放大小 默认为1.0f
datescale 日期文本的缩放大小 默认为1.0f
downcolor 按下时,圆的颜色 默认为0x00000000
ischinese 星期与年月的显示是否为中文 默认为false
weekcolor 星期文本的颜色 默认为0xFF000000


思路:

1.排除掉这些自定义属性,我们要实现一个日历的基本功能(改变月份时,日历上的日期也会改变),那我们需要两样重要的东西来实现:存放日期的数字的数组或list记录位置的索引

2.当基本功能完成后,我们就要确认下绘制顺序,这个比较简单

3.加入上面的属性,并加入一些限制,放置使用者把这个控件玩脱了


先上全部源码吧:

[java] view plain copy
  1. package calendar;  
  2.   
  3. import android.content.Context;  
  4. import android.content.res.TypedArray;  
  5. import android.graphics.Bitmap;  
  6. import android.graphics.BitmapFactory;  
  7. import android.graphics.Canvas;  
  8. import android.graphics.Color;  
  9. import android.graphics.Paint;  
  10. import android.graphics.RectF;  
  11. import android.graphics.Typeface;  
  12. import android.util.AttributeSet;  
  13. import android.util.Log;  
  14. import android.view.MotionEvent;  
  15. import android.view.View;  
  16.   
  17. import com.example.peng.myapplication.R;  
  18.   
  19. import java.util.ArrayList;  
  20. import java.util.Calendar;  
  21. import java.util.Date;  
  22. import java.util.List;  
  23.   
  24.   
  25. /** 
  26.  * Created by peng on 2017/5/5. 
  27.  */  
  28.   
  29. public class CalendarView extends View implements View.OnTouchListener{  
  30.     float width,height;//控件的宽与高  
  31.     float c_width,c_height;//日历的宽与高  
  32.     float monthHeight;//年月所在格子的高度,也是两个按钮的实际宽与高  
  33.     float weekHeight;//星期所在格子的高度  
  34.     float cell_width,cell_height;//小格子的宽与高  
  35.     float wpadding,hpadding;//与左右,上下的间距  
  36.     boolean isChinese;//星期是否中文  
  37.     boolean isBold;//文本是否加粗  
  38.     boolean bg1IsFill;//背景1是否填充  
  39.     boolean bg2IsFill;//背景2是否填充  
  40.     RectF c_rect = new RectF();  
  41.     RectF bg2_rect = new RectF();  
  42.     float r;//小圆圈的半径,给日期当背景的  
  43.     float distance;//按钮与两边的距离  
  44.   
  45.     Paint bg1Paint = new Paint();//年月背景1的画笔  
  46.     Paint bg2Paint = new Paint();//年月背景2的画笔  
  47.     Paint monthPaint = new Paint();//年月文本的画笔  
  48.     Paint weekPaint = new Paint();//上面一排星期文本的画笔  
  49.     Paint broderPaint = new Paint();//边框线的画笔  
  50.     Paint downBgPaint = new Paint();//绘制背景的画笔  
  51.     Paint testPaint = new Paint();//测试的画笔  
  52.   
  53.   
  54.     int bg1Color;//年月背景1的颜色  
  55.     int bg2Color;//年月背景2的颜色  
  56.     int downBgColor;//按下时的背景颜色  
  57.     int weekColor;//星期文本颜色  
  58.     int broderColor;//边框颜色  
  59.     //int dateColor;  
  60.     int[] dateColors = new int[3];//分别为 上个月或下个月日期的颜色,当前月的颜色,当前日期的颜色  
  61.   
  62.     float weekScale = 1.0f;  
  63.     float dateScale = 1.0f;  
  64.   
  65.   
  66.     Paint datePaint = new Paint();  
  67.   
  68.     public String[] weekText = { "Sun","Mon""Tue""Wed""Thu""Fri""Sat"};  
  69.     public int[] date = new int[42];  
  70.     List<CenterPoint> centerPointList = new ArrayList<CenterPoint>();//42个格子的中心点  
  71.   
  72.     private Date curDate;   // 当前日历显示的日期  
  73.     private Date today;     // 今天的日期  
  74.     private int curyear,curmonth;//当前的年月  
  75.     private Calendar calendar,todayCalendar;  
  76.     private int curStartIndex, curEndIndex; // 当前显示的日历起始的索引  
  77.   
  78.     private boolean down = false;//是否按在有效区域  
  79.     private int downIndex;//按下的区域索引,0-41为日期,42为左键,43为右键  
  80.   
  81.     //左右箭头  
  82.     Bitmap pre = BitmapFactory.decodeResource(getResources(),R.drawable.calendar_month_left);  
  83.     Bitmap next = BitmapFactory.decodeResource(getResources(),R.drawable.calendar_month_right);  
  84.   
  85.     public CalendarView(Context context) {  
  86.         this(context, null);  
  87.     }  
  88.   
  89.     public CalendarView(Context context, AttributeSet attrs) {  
  90.         super(context, attrs);  
  91.         TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.Calendar);  
  92.         wpadding = ta.getFloat(R.styleable.Calendar_wpadding,0f);//xml中的左右间距  
  93.         hpadding = ta.getFloat(R.styleable.Calendar_hpadding,0f);//xml中的上下间距  
  94.   
  95.         bg1Color = ta.getColor(R.styleable.Calendar_monthbg1color, 0x00000000);//xml中年月背景1的颜色  
  96.         bg2Color = ta.getColor(R.styleable.Calendar_monthbg2color, 0x00000000);//xml中年月背景1的颜色  
  97.         downBgColor = ta.getColor(R.styleable.Calendar_downcolor, 0x00000000);//xml中按下有效区域时的颜色  
  98.         weekColor = ta.getColor(R.styleable.Calendar_weekcolor, 0xFF000000);//xml中星期文本颜色  
  99.         broderColor = ta.getColor(R.styleable.Calendar_bordercolor, 0x00000000);//xml中边框颜色  
  100.         dateColors[0] = ta.getColor(R.styleable.Calendar_othermonthcolor, 0xFFCCCCCC);//xml中日期文本颜色  
  101.         dateColors[1] = ta.getColor(R.styleable.Calendar_normalcolor,0xFF000000);//xml中日期文本颜色  
  102.         dateColors[2] = ta.getColor(R.styleable.Calendar_todaycolor,0xFFFF0000);//xml中日期文本颜色  
  103.   
  104.         bg1Paint.setColor(bg1Color);  
  105.         bg2Paint.setColor(bg2Color);  
  106.         downBgPaint.setColor(downBgColor);  
  107.         weekPaint.setColor(weekColor);  
  108.         broderPaint.setColor(broderColor);  
  109.         datePaint.setColor(dateColors[1]);  
  110.   
  111.         weekScale = ta.getFloat(R.styleable.Calendar_weekscale,1.0f);//星期的缩小倍数  
  112.         weekScale = weekScale<1.0f?weekScale:1.0f;  
  113.         dateScale = ta.getFloat(R.styleable.Calendar_datescale,1.0f);//日期的缩小倍数  
  114.         dateScale = dateScale<1.0f?dateScale:1.0f;  
  115.         distance = ta.getFloat(R.styleable.Calendar_buttondistance,0f);//两个按钮与两边的距离  
  116.   
  117.         isBold = ta.getBoolean(R.styleable.Calendar_isbold, false);//xml中文本是否加粗  
  118.         isChinese = ta.getBoolean(R.styleable.Calendar_ischinese,false);//xml中星期文本是否中文  
  119.         bg1IsFill = ta.getBoolean(R.styleable.Calendar_monthbg1fill,false);//xml中年月背景1是否填充  
  120.         bg2IsFill = ta.getBoolean(R.styleable.Calendar_monthbg1fill,false);//xml中年月背景2是否填充  
  121.   
  122.         ta.recycle();  
  123.         init();  
  124.     }  
  125.   
  126.     private void init(){  
  127.         curDate = today = new Date();//初始化日期  
  128.         todayCalendar = Calendar.getInstance();  
  129.         todayCalendar.setTime(today);  
  130.   
  131.         calendar = Calendar.getInstance();  
  132.         calendar.setTime(curDate);  
  133.   
  134.         broderPaint.setStyle(Paint.Style.STROKE);  
  135.         broderPaint.setStrokeWidth(5);  
  136.         broderPaint.setAntiAlias(true);  
  137.   
  138.   
  139.         bg1Paint.setStrokeWidth(5);  
  140.         bg1Paint.setAntiAlias(true);  
  141.   
  142.         bg2Paint.setStrokeWidth(5);  
  143.         bg2Paint.setAntiAlias(true);  
  144.   
  145.         downBgPaint.setAntiAlias(true);  
  146.   
  147.         monthPaint.setAntiAlias(true);  
  148.         monthPaint.setTextAlign(Paint.Align.CENTER);  
  149.   
  150.         weekPaint.setAntiAlias(true);  
  151.         weekPaint.setTextAlign(Paint.Align.CENTER);  
  152.   
  153.         datePaint.setAntiAlias(true);  
  154.         datePaint.setTextAlign(Paint.Align.CENTER);  
  155.         testPaint.setColor(Color.BLUE);  
  156.   
  157.         if(isBold){  
  158.             monthPaint.setTypeface(Typeface.DEFAULT_BOLD);  
  159.             weekPaint.setTypeface(Typeface.DEFAULT_BOLD);  
  160.             datePaint.setTypeface(Typeface.DEFAULT_BOLD);  
  161.         }  
  162.   
  163.         if(bg1IsFill){  
  164.             bg1Paint.setStyle(Paint.Style.FILL);  
  165.         }else{  
  166.             bg1Paint.setStyle(Paint.Style.STROKE);  
  167.         }  
  168.         if(bg2IsFill){  
  169.             bg2Paint.setStyle(Paint.Style.FILL);  
  170.         }else{  
  171.             bg2Paint.setStyle(Paint.Style.STROKE);  
  172.         }  
  173.   
  174.         if(isChinese){  
  175.             weekText = new String[]{ "星期日","星期一""星期二""星期三""星期四""星期五""星期六"};  
  176.         }else{  
  177.             weekText = new String[]{ "Sun","Mon""Tue""Wed""Thu""Fri""Sat"};  
  178.         }  
  179.   
  180.         setOnTouchListener(this);  
  181.   
  182.   
  183.     }  
  184.   
  185.   
  186.   
  187.     @Override  
  188.     protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {  
  189.         super.onMeasure(widthMeasureSpec, heightMeasureSpec);  
  190.         width = getResources().getDisplayMetrics().widthPixels;  
  191.         height = getResources().getDisplayMetrics().heightPixels;  
  192.   
  193.   
  194.   
  195.         wpadding = wpadding < width/20f? wpadding:width/20f;  
  196.         hpadding = hpadding < height/20f? hpadding:height/20f;  
  197.   
  198.         c_width = width - 2*wpadding;  
  199.         c_height = height*2/5 - 2*hpadding;  
  200.   
  201.         weekHeight = c_height/10f;  
  202.         monthHeight = weekHeight*3/2;  
  203.         pre = DrawTool.changeSize(pre, monthHeight, monthHeight);  
  204.         next = DrawTool.changeSize(next, monthHeight, monthHeight);  
  205.   
  206.   
  207.         c_rect.left = wpadding;  
  208.         c_rect.top = monthHeight + weekHeight + hpadding;  
  209.         c_rect.right = wpadding + c_width;  
  210.         c_rect.bottom = monthHeight + weekHeight + hpadding + c_height;  
  211.   
  212.         //bg2   宽: width/3    高:monthHeight*4/5  
  213.         bg2_rect.left = (width - (width-2*wpadding)/3)/2;  
  214.         bg2_rect.top = (monthHeight - monthHeight*4/5)/2 + hpadding;  
  215.         bg2_rect.right = (width - (width-2*wpadding)/3)/2 + (width-2*wpadding)/3;  
  216.         bg2_rect.bottom = (monthHeight - monthHeight*4/5)/2 + monthHeight*4/5 +hpadding;  
  217.   
  218.         cell_width = (c_width)/7f;  
  219.         cell_height = (c_height)/6f;  
  220.   
  221.         distance = Math.min(distance, (width - 2 * wpadding) / 5);  
  222.   
  223.         //小圆圈的半径  
  224.         r = Math.min(cell_width,cell_height)*4/5*1/2;  
  225.   
  226.         monthPaint.setTextSize(cell_height * 2/3);  
  227.         weekPaint.setTextSize(cell_height / 2 * weekScale);  
  228.         datePaint.setTextSize(cell_height / 2 * dateScale);  
  229.   
  230.         /* 
  231.             获取所有小格子的中心点 
  232.             1.这个中心点可以用来辅助绘制文本 
  233.             2.这个中心点可以辅助绘制圆 
  234.          */  
  235.         centerPointList.clear();  
  236.         for(int i=0;i<date.length;i++){  
  237.             centerPointList.add(new CenterPoint(wpadding + cell_width/2 + (int)(cell_width*(i%7)),  
  238.                             monthHeight + weekHeight + hpadding + cell_height/2 + (cell_height*(i/7))));  
  239.         }  
  240.   
  241.         heightMeasureSpec = MeasureSpec.makeMeasureSpec((int)(2*hpadding + monthHeight + weekHeight + c_height),  
  242.                 MeasureSpec.EXACTLY);  
  243.         setMeasuredDimension(widthMeasureSpec, heightMeasureSpec);  
  244.     }  
  245.   
  246.     @Override  
  247.     protected void onDraw(Canvas canvas) {  
  248.         super.onDraw(canvas);  
  249.         calculateDate();  
  250.         drawBg(canvas);  
  251.         drawDownBg(canvas);  
  252.         drawMonth_Year(canvas);  
  253.         drawWeek(canvas);  
  254.         drawCell(canvas);  
  255.         drawDate(canvas);  
  256.   
  257.   
  258.     }  
  259.   
  260.     //绘制年与月背景  
  261.     private void drawBg(Canvas canvas){  
  262.         canvas.drawRect(0,hpadding,width,hpadding+monthHeight,bg1Paint);  
  263.         canvas.drawRoundRect(bg2_rect,10,10,bg2Paint);  
  264.     }  
  265.     //绘制按下背景颜色,即按下后的背景  
  266.     private void drawDownBg(Canvas canvas){  
  267.         if(down){  
  268.             //这里按下左右减只是改背景色,也可以改图片,按自己需求来改  
  269.             if((downIndex>=0)&&(downIndex<42)){  
  270.                 canvas.drawCircle(centerPointList.get(downIndex).pointX,centerPointList.get(downIndex).pointY,r,downBgPaint);  
  271.             }  
  272.             if(downIndex == 42){  
  273.                 canvas.drawRect(wpadding + distance,hpadding + (monthHeight - pre.getHeight()) / 2,wpadding+distance+pre.getWidth(),hpadding + (monthHeight - pre.getHeight()) / 2+pre.getHeight(),downBgPaint);  
  274.             }else if(downIndex == 43){  
  275.                 canvas.drawRect(width - wpadding - next.getWidth()-distance,hpadding + (monthHeight - next.getHeight()) / 2,width - wpadding-distance,hpadding + (monthHeight - next.getHeight()) / 2 +next.getHeight(),downBgPaint);  
  276.             }  
  277.         }  
  278.     }  
  279.     //绘制年与月相关控件  
  280.     private void drawMonth_Year(Canvas canvas){  
  281.         //canvas.drawRect(0,hpadding,width,monthHeight+hpadding,testPaint);  
  282.         canvas.drawBitmap(pre, wpadding + distance, hpadding + (monthHeight - pre.getHeight()) / 2null);  
  283.         canvas.drawBitmap(next, width - wpadding - next.getWidth()-distance, hpadding + (monthHeight - next.getHeight()) / 2null);  
  284.   
  285.         Paint.FontMetrics fontMetrics = datePaint.getFontMetrics();  
  286.         float baseline = (fontMetrics.bottom - fontMetrics.top)/2 -fontMetrics.bottom;  
  287.         String year_month_text = "";  
  288.         if(isChinese){  
  289.             if (curmonth<10){  
  290.                 year_month_text = curyear +"年"+"0"+curmonth+"月";  
  291.             }else{  
  292.                 year_month_text = curyear +"年"+curmonth+"月";  
  293.             }  
  294.   
  295.         }else{  
  296.             if (curmonth<10){  
  297.                 year_month_text = curyear +"-"+"0"+curmonth;  
  298.             }else{  
  299.                 year_month_text = curyear +"-"+curmonth;  
  300.             }  
  301.         }  
  302.         canvas.drawText(year_month_text, width / 2, hpadding + monthHeight / 2f + baseline, monthPaint);  
  303.   
  304.   
  305.   
  306.     }  
  307.     //绘制星期文本  
  308.     private void drawWeek(Canvas canvas){  
  309.         float weekTextY = hpadding + monthHeight + weekHeight * 3 / 4f;  
  310.         for(int i=0;i<weekText.length;i++){  
  311.             /* 
  312.             float weekTextX = wpadding + (i* cell_width) 
  313.                     + (cell_width - weekPaint.measureText(weekText[i])) / 2f; 
  314.             */  
  315.             float weekTextX = wpadding + (i* cell_width) + cell_width/2;  
  316.             canvas.drawText(weekText[i], weekTextX, weekTextY,  
  317.                     weekPaint);  
  318.         }  
  319.     }  
  320.     //绘制框框  
  321.     private void drawCell(Canvas canvas){  
  322.         canvas.drawRoundRect(c_rect, 1515, broderPaint);  
  323.         //画横线  
  324.         for(int i=1;i<6;i++){  
  325.             canvas.drawLine(wpadding,monthHeight + weekHeight + hpadding+(i*cell_height),wpadding+c_width,monthHeight + weekHeight + hpadding+(i*cell_height),broderPaint);  
  326.         }  
  327.         //画竖线  
  328.         for(int i=1;i<7;i++){  
  329.             canvas.drawLine(wpadding + (i * cell_width), monthHeight + weekHeight + hpadding, wpadding + (i * cell_width), hpadding + monthHeight + weekHeight + c_height, broderPaint);  
  330.         }  
  331.     }  
  332.     //绘制日期文本  
  333.     private void drawDate(Canvas canvas){  
  334.         Paint.FontMetrics fontMetrics = datePaint.getFontMetrics();  
  335.         float baseline = (fontMetrics.bottom - fontMetrics.top)/2 -fontMetrics.bottom;  
  336.         /* 
  337.         Log.d("test", "bottom: " + fontMetrics.bottom + ", top: " + fontMetrics.top 
  338.                         + ", ascent: " + fontMetrics.ascent 
  339.                         + ", descent: " + fontMetrics.descent 
  340.                         + ", leading: " + fontMetrics.leading); 
  341.         */  
  342.         for(int i=0;i<date.length;i++){  
  343.             int color = dateColors[1];  
  344.             if (isLastMonth(i)) {  
  345.                 color = dateColors[0];  
  346.             } else if (isNextMonth(i)) {  
  347.                 color = dateColors[0];  
  348.             }else if(isToday(date[i])){  
  349.                 color = dateColors[2];  
  350.             }  
  351.             datePaint.setColor(color);  
  352.             canvas.drawText(date[i] + "", centerPointList.get(i).pointX, centerPointList.get(i).pointY + baseline, datePaint);  
  353.         }  
  354.     }  
  355.   
  356.   
  357.     @Override  
  358.     public boolean onTouch(View v, MotionEvent event) {  
  359.         switch (event.getAction()) {  
  360.             case MotionEvent.ACTION_DOWN:  
  361.                 if((event.getX()>wpadding)&&//在日期区域  
  362.                    (event.getX()<wpadding + c_width)&&  
  363.                    (event.getY()>monthHeight + weekHeight + hpadding)&&  
  364.                    (event.getY()<hpadding + monthHeight + weekHeight + c_height)){  
  365.   
  366.                     getSelectedDate(event.getX() - wpadding, event.getY() - (hpadding + monthHeight + weekHeight));  
  367.   
  368.                 }  
  369.                 else if((event.getX()>wpadding+distance)&&//点击pre按钮  
  370.                         (event.getX()<wpadding + distance +pre.getWidth())&&  
  371.                         (event.getY()>hpadding)&&  
  372.                         (event.getY()<hpadding + pre.getHeight())){  
  373.   
  374.                     clickLeftMonth();  
  375.   
  376.                 }  
  377.                 else if((event.getX()>width-wpadding-distance-next.getWidth())&&//点击pre按钮  
  378.                          (event.getX()<width-wpadding-distance)&&  
  379.                          (event.getY()>hpadding)&&  
  380.                          (event.getY()<hpadding + next.getHeight())){  
  381.   
  382.                     clickRightMonth();  
  383.   
  384.                 }  
  385.                 break;  
  386.             case MotionEvent.ACTION_UP:  
  387.                 down = false;  
  388.                 downIndex = 0;  
  389.                 invalidate();  
  390.                 break;  
  391.   
  392.         }  
  393.   
  394.         return true;  
  395.     }  
  396.   
  397.     //获取点击到的日期"索引"  
  398.     private void getSelectedDate(float x, float y){  
  399.         int m = (int)(Math.floor((x/cell_width)) + 1);  
  400.         int n = (int)(Math.floor((y/cell_height)) + 1);  
  401.         int index = (n-1)*7 + (m-1);  
  402.         Log.d("test""getSelectedDate: " + index);  
  403.         down = true;  
  404.         downIndex = index;  
  405.         invalidate();  
  406.   
  407.     }  
  408.   
  409.     //计算日期,填充时间  
  410.     private void calculateDate() {  
  411.         calendar.setTime(curDate);  
  412.         curyear = calendar.get(Calendar.YEAR);  
  413.         curmonth = calendar.get(Calendar.MONTH)+1;  
  414.         Log.d("test""curyear:" + curyear + ", curmonth:" + curmonth );  
  415.         calendar.set(Calendar.DAY_OF_MONTH, 1);  
  416.         int dayInWeek = calendar.get(Calendar.DAY_OF_WEEK);//获取当前是星期几  
  417.         int monthStart = dayInWeek;//当月1号是星期几,辅助后面填充日期的  
  418.         if (monthStart == 1) {  
  419.             monthStart = 8;  
  420.         }  
  421.         monthStart -= 1;  //以日为开头-1,以星期一为开头-2  
  422.         curStartIndex = monthStart;  
  423.         //TODO 向date数组填充1号  
  424.         date[monthStart] = 1;  
  425.         //TODO 向date数组填充1号前面的日期  
  426.         if (monthStart > 0) {  
  427.             calendar.set(Calendar.DAY_OF_MONTH, 0);  
  428.             //TODO 这个是第一天的前面的一天,也就是上个月月尾  
  429.             int dayInmonth = calendar.get(Calendar.DAY_OF_MONTH);  
  430.             for (int i = monthStart - 1; i >= 0; i--) {  
  431.                 date[i] = dayInmonth;  
  432.                 dayInmonth--;  
  433.             }  
  434.             calendar.set(Calendar.DAY_OF_MONTH, date[0]);  
  435.         }  
  436.   
  437.         //TODO 获取这个月的月尾  
  438.         calendar.setTime(curDate);  
  439.         calendar.add(Calendar.MONTH, 1);  
  440.         calendar.set(Calendar.DAY_OF_MONTH, 0);  
  441.   
  442.         //TODO 向date数组填充1号之后到月尾的日期  
  443.         int monthDay = calendar.get(Calendar.DAY_OF_MONTH);  
  444.         for (int i = 1; i < monthDay; i++) {  
  445.             date[monthStart + i] = i + 1;  
  446.         }  
  447.   
  448.         //TODO 向date数组填充月尾后的日期  
  449.         curEndIndex = monthStart + monthDay;  
  450.         for (int i = monthStart + monthDay; i < 42; i++) {  
  451.             date[i] = i - (monthStart + monthDay) + 1;  
  452.         }  
  453.   
  454.   
  455.   
  456.     }  
  457.     //是否上个月  
  458.     private boolean isLastMonth(int i) {  
  459.         if (i < curStartIndex) {  
  460.             return true;  
  461.         }  
  462.         return false;  
  463.     }  
  464.   
  465.     //是否下个月  
  466.     private boolean isNextMonth(int i) {  
  467.         if (i >= curEndIndex) {  
  468.             return true;  
  469.         }  
  470.         return false;  
  471.     }  
  472.   
  473.     //是否今天  
  474.     private boolean isToday(int i) {  
  475.         calendar.setTime(curDate);  
  476.         if((calendar.get(Calendar.YEAR)==todayCalendar.get(Calendar.YEAR))&&  
  477.                 (calendar.get(Calendar.MONTH)==todayCalendar.get(Calendar.MONTH))){  
  478.   
  479.             if(i == todayCalendar.get(Calendar.DAY_OF_MONTH)){  
  480.                 return true;  
  481.             }else{  
  482.                 return false;  
  483.             }  
  484.   
  485.         }  
  486.   
  487.         return false;  
  488.     }  
  489.   
  490.     //TODO 上一月,计算但前页面的月份,注意curDate  
  491.     public void clickLeftMonth(){  
  492.         calendar.setTime(curDate);  
  493.         calendar.add(Calendar.MONTH, -1);  
  494.         curDate = calendar.getTime();  
  495.         //Log.d("getTimetest", "y:" + (calendar.get(Calendar.MONTH)+1) + " ,d:" + calendar.get(Calendar.DAY_OF_MONTH));  
  496.         down = true;  
  497.         downIndex = 42;  
  498.         invalidate();  
  499.     }  
  500.     //TODO 下一月,计算但前页面的月份,注意curDate  
  501.     public void clickRightMonth(){  
  502.         calendar.setTime(curDate);  
  503.         calendar.add(Calendar.MONTH, 1);  
  504.         curDate = calendar.getTime();  
  505.         //Log.d("getTimetest", "y:" + (calendar.get(Calendar.MONTH)+1) + " ,d:" + calendar.get(Calendar.DAY_OF_MONTH));  
  506.         down = true;  
  507.         downIndex = 43;  
  508.         invalidate();  
  509.     }  
  510.   
  511. }  


要实现1,我们要用到下面三个方法:

private void calculateDate()

public void clickLeftMonth()
public void clickRightMonth()


后面两个方法比较容易理解,主要讲下前面一个:calculateDate()

1.这个主要先用临时calendar获取curdate(这是当前页面的日期,随着页面改变而改变)的时间

2.接着利用这个calendar获取“星期”,利用“星期”获取索引 "monthStart" (这个索引就是用来辅助填充,日历中,当前月份的第一天与上个月末尾几天)

3.再利用当前月月末的日期获取索引"monthDay" (这个是用来辅助填充,日历中,当前月份的第二天与这个月月末)

4.最后填充下个月月初几天,直到将日历数组中42个元素填满

相关文章: