Android UI-自定义日历控件

来源:互联网 发布:plm软件有哪些 编辑:程序博客网 时间:2024/04/27 21:03

Android UI-自定义日历控件


本篇博客笔者给大家分享一个日历控件,这里有个需求:要求显示当前月的日期,左右可以切换月份来查看日期。

我们想一想会如何去实现这样的一个控件,有开源的,但可能不太满足我们的特定的需求,这里笔者自定义了一个,读者可以根据自己的需求来修改代码。下面来说一下实现的思路:

首先我们要显示当前月份,自然我们要计算出当前的日期,并且把每一天对应到具体的星期,我们会有以下效果:

我们先想一下这样的效果用什么控件可以实现?很自然可以想到用网格视图GridView,但这里笔者使用的不是GridView, 因为使用GridView可能无法实现那个红色的圈圈,所以笔者决定自定义View,通过绘制来达到这样的效果。

这里我们定于一个日历卡,每一个月代表一个日历卡,我们通过计算每个月的日期,然后根据计算出来的位置绘制我们的数字。

我们知道,一个星期有七天,分别为星期日、星期一、星期二、星期三、星期四、星期五、星期六,这里有7列,一个月至少有28天,最多31天,所以至少应该有6行。组成6*7的方格图。

直接上代码:

[java] view plaincopy在CODE上查看代码片派生到我的代码片
  1. package com.xiaowu.calendar;  
  2.   
  3. import android.content.Context;  
  4. import android.graphics.Canvas;  
  5. import android.graphics.Color;  
  6. import android.graphics.Paint;  
  7. import android.util.AttributeSet;  
  8. import android.view.MotionEvent;  
  9. import android.view.View;  
  10. import android.view.ViewConfiguration;  
  11.   
  12. /** 
  13.  * 自定义日历卡 
  14.  *  

  15.  *  
  16.  */  
  17. public class CalendarCard extends View {  
  18.   
  19.     private static final int TOTAL_COL = 7// 7列  
  20.     private static final int TOTAL_ROW = 6// 6行  
  21.   
  22.     private Paint mCirclePaint; // 绘制圆形的画笔  
  23.     private Paint mTextPaint; // 绘制文本的画笔  
  24.     private int mViewWidth; // 视图的宽度  
  25.     private int mViewHeight; // 视图的高度  
  26.     private int mCellSpace; // 单元格间距  
  27.     private Row rows[] = new Row[TOTAL_ROW]; // 行数组,每个元素代表一行  
  28.     private static CustomDate mShowDate; // 自定义的日期,包括year,month,day  
  29.     private OnCellClickListener mCellClickListener; // 单元格点击回调事件  
  30.     private int touchSlop; //  
  31.     private boolean callBackCellSpace;  
  32.   
  33.     private Cell mClickCell;  
  34.     private float mDownX;  
  35.     private float mDownY;  
  36.   
  37.     /** 
  38.      * 单元格点击的回调接口 
  39.      *  
  40.      * @author wuwenjie 
  41.      *  
  42.      */  
  43.     public interface OnCellClickListener {  
  44.         void clickDate(CustomDate date); // 回调点击的日期  
  45.   
  46.         void changeDate(CustomDate date); // 回调滑动ViewPager改变的日期  
  47.     }  
  48.   
  49.     public CalendarCard(Context context, AttributeSet attrs, int defStyleAttr) {  
  50.         super(context, attrs, defStyleAttr);  
  51.         init(context);  
  52.     }  
  53.   
  54.     public CalendarCard(Context context, AttributeSet attrs) {  
  55.         super(context, attrs);  
  56.         init(context);  
  57.     }  
  58.   
  59.     public CalendarCard(Context context) {  
  60.         super(context);  
  61.         init(context);  
  62.     }  
  63.   
  64.     public CalendarCard(Context context, OnCellClickListener listener) {  
  65.         super(context);  
  66.         this.mCellClickListener = listener;  
  67.         init(context);  
  68.     }  
  69.   
  70.     private void init(Context context) {  
  71.         mTextPaint = new Paint(Paint.ANTI_ALIAS_FLAG);  
  72.         mCirclePaint = new Paint(Paint.ANTI_ALIAS_FLAG);  
  73.         mCirclePaint.setStyle(Paint.Style.FILL);  
  74.         mCirclePaint.setColor(Color.parseColor("#F24949")); // 红色圆形  
  75.         touchSlop = ViewConfiguration.get(context).getScaledTouchSlop();  
  76.   
  77.         initDate();  
  78.     }  
  79.   
  80.     private void initDate() {  
  81.         mShowDate = new CustomDate();  
  82.         fillDate();//  
  83.     }  
  84.   
  85.     private void fillDate() {  
  86.         int monthDay = DateUtil.getCurrentMonthDay(); // 今天  
  87.         int lastMonthDays = DateUtil.getMonthDays(mShowDate.year,  
  88.                 mShowDate.month - 1); // 上个月的天数  
  89.         int currentMonthDays = DateUtil.getMonthDays(mShowDate.year,  
  90.                 mShowDate.month); // 当前月的天数  
  91.         int firstDayWeek = DateUtil.getWeekDayFromDate(mShowDate.year,  
  92.                 mShowDate.month);  
  93.         boolean isCurrentMonth = false;  
  94.         if (DateUtil.isCurrentMonth(mShowDate)) {  
  95.             isCurrentMonth = true;  
  96.         }  
  97.         int day = 0;  
  98.         for (int j = 0; j < TOTAL_ROW; j++) {  
  99.             rows[j] = new Row(j);  
  100.             for (int i = 0; i < TOTAL_COL; i++) {  
  101.                 int position = i + j * TOTAL_COL; // 单元格位置  
  102.                 // 这个月的  
  103.                 if (position >= firstDayWeek  
  104.                         && position < firstDayWeek + currentMonthDays) {  
  105.                     day++;  
  106.                     rows[j].cells[i] = new Cell(CustomDate.modifiDayForObject(  
  107.                             mShowDate, day), State.CURRENT_MONTH_DAY, i, j);  
  108.                     // 今天  
  109.                     if (isCurrentMonth && day == monthDay ) {  
  110.                         CustomDate date = CustomDate.modifiDayForObject(mShowDate, day);  
  111.                         rows[j].cells[i] = new Cell(date, State.TODAY, i, j);  
  112.                     }  
  113.   
  114.                     if (isCurrentMonth && day > monthDay) { // 如果比这个月的今天要大,表示还没到  
  115.                         rows[j].cells[i] = new Cell(  
  116.                                 CustomDate.modifiDayForObject(mShowDate, day),  
  117.                                 State.UNREACH_DAY, i, j);  
  118.                     }  
  119.   
  120.                     // 过去一个月  
  121.                 } else if (position < firstDayWeek) {  
  122.                     rows[j].cells[i] = new Cell(new CustomDate(mShowDate.year,  
  123.                             mShowDate.month - 1, lastMonthDays  
  124.                                     - (firstDayWeek - position - 1)),  
  125.                             State.PAST_MONTH_DAY, i, j);  
  126.                     // 下个月  
  127.                 } else if (position >= firstDayWeek + currentMonthDays) {  
  128.                     rows[j].cells[i] = new Cell((new CustomDate(mShowDate.year,  
  129.                             mShowDate.month + 1, position - firstDayWeek  
  130.                                     - currentMonthDays + 1)),  
  131.                             State.NEXT_MONTH_DAY, i, j);  
  132.                 }  
  133.             }  
  134.         }  
  135.         mCellClickListener.changeDate(mShowDate);  
  136.     }  
  137.   
  138.     @Override  
  139.     protected void onDraw(Canvas canvas) {  
  140.         super.onDraw(canvas);  
  141.         for (int i = 0; i < TOTAL_ROW; i++) {  
  142.             if (rows[i] != null) {  
  143.                 rows[i].drawCells(canvas);  
  144.             }  
  145.         }  
  146.     }  
  147.   
  148.     @Override  
  149.     protected void onSizeChanged(int w, int h, int oldw, int oldh) {  
  150.         super.onSizeChanged(w, h, oldw, oldh);  
  151.         mViewWidth = w;  
  152.         mViewHeight = h;  
  153.         mCellSpace = Math.min(mViewHeight / TOTAL_ROW, mViewWidth / TOTAL_COL);  
  154.         if (!callBackCellSpace) {  
  155.             callBackCellSpace = true;  
  156.         }  
  157.         mTextPaint.setTextSize(mCellSpace / 3);  
  158.     }  
  159.   
  160.     @Override  
  161.     public boolean onTouchEvent(MotionEvent event) {  
  162.         switch (event.getAction()) {  
  163.         case MotionEvent.ACTION_DOWN:  
  164.             mDownX = event.getX();  
  165.             mDownY = event.getY();  
  166.             break;  
  167.         case MotionEvent.ACTION_UP:  
  168.             float disX = event.getX() - mDownX;  
  169.             float disY = event.getY() - mDownY;  
  170.             if (Math.abs(disX) < touchSlop && Math.abs(disY) < touchSlop) {  
  171.                 int col = (int) (mDownX / mCellSpace);  
  172.                 int row = (int) (mDownY / mCellSpace);  
  173.                 measureClickCell(col, row);  
  174.             }  
  175.             break;  
  176.         default:  
  177.             break;  
  178.         }  
  179.   
  180.         return true;  
  181.     }  
  182.   
  183.     /** 
  184.      * 计算点击的单元格 
  185.      * @param col 
  186.      * @param row 
  187.      */  
  188.     private void measureClickCell(int col, int row) {  
  189.         if (col >= TOTAL_COL || row >= TOTAL_ROW)  
  190.             return;  
  191.         if (mClickCell != null) {  
  192.             rows[mClickCell.j].cells[mClickCell.i] = mClickCell;  
  193.         }  
  194.         if (rows[row] != null) {  
  195.             mClickCell = new Cell(rows[row].cells[col].date,  
  196.                     rows[row].cells[col].state, rows[row].cells[col].i,  
  197.                     rows[row].cells[col].j);  
  198.   
  199.             CustomDate date = rows[row].cells[col].date;  
  200.             date.week = col;  
  201.             mCellClickListener.clickDate(date);  
  202.   
  203.             // 刷新界面  
  204.             update();  
  205.         }  
  206.     }  
  207.   
  208.     /** 
  209.      * 组元素 
  210.      * 
  211.      *  
  212.      */  
  213.     class Row {  
  214.         public int j;  
  215.   
  216.         Row(int j) {  
  217.             this.j = j;  
  218.         }  
  219.   
  220.         public Cell[] cells = new Cell[TOTAL_COL];  
  221.   
  222.         // 绘制单元格  
  223.         public void drawCells(Canvas canvas) {  
  224.             for (int i = 0; i < cells.length; i++) {  
  225.                 if (cells[i] != null) {  
  226.                     cells[i].drawSelf(canvas);  
  227.                 }  
  228.             }  
  229.         }  
  230.   
  231.     }  
  232.   
  233.     /** 
  234.      * 单元格元素 
  235.      *  
  236.     
  237.      *  
  238.      */  
  239.     class Cell {  
  240.         public CustomDate date;  
  241.         public State state;  
  242.         public int i;  
  243.         public int j;  
  244.   
  245.         public Cell(CustomDate date, State state, int i, int j) {  
  246.             super();  
  247.             this.date = date;  
  248.             this.state = state;  
  249.             this.i = i;  
  250.             this.j = j;  
  251.         }  
  252.   
  253.         public void drawSelf(Canvas canvas) {  
  254.             switch (state) {  
  255.             case TODAY: // 今天  
  256.                 mTextPaint.setColor(Color.parseColor("#fffffe"));  
  257.                 canvas.drawCircle((float) (mCellSpace * (i + 0.5)),  
  258.                         (float) ((j + 0.5) * mCellSpace), mCellSpace / 3,  
  259.                         mCirclePaint);  
  260.                 break;  
  261.             case CURRENT_MONTH_DAY: // 当前月日期  
  262.                 mTextPaint.setColor(Color.BLACK);  
  263.                 break;  
  264.             case PAST_MONTH_DAY: // 过去一个月  
  265.             case NEXT_MONTH_DAY: // 下一个月  
  266.                 mTextPaint.setColor(Color.parseColor("#fffffe"));  
  267.                 break;  
  268.             case UNREACH_DAY: // 还未到的天  
  269.                 mTextPaint.setColor(Color.GRAY);  
  270.                 break;  
  271.             default:  
  272.                 break;  
  273.             }  
  274.             // 绘制文字  
  275.             String content = date.day + "";  
  276.             canvas.drawText(content,  
  277.                     (float) ((i + 0.5) * mCellSpace - mTextPaint  
  278.                             .measureText(content) / 2), (float) ((j + 0.7)  
  279.                             * mCellSpace - mTextPaint  
  280.                             .measureText(content, 01) / 2), mTextPaint);  
  281.         }  
  282.     }  
  283.   
  284.     /** 
  285.      *  
  286.      单元格的状态 当前月日期,过去的月的日期,下个月的日期 
  287.      */  
  288.     enum State {  
  289.         TODAY,CURRENT_MONTH_DAY, PAST_MONTH_DAY, NEXT_MONTH_DAY, UNREACH_DAY;  
  290.     }  
  291.   
  292.     // 从左往右划,上一个月  
  293.     public void leftSlide() {  
  294.         if (mShowDate.month == 1) {  
  295.             mShowDate.month = 12;  
  296.             mShowDate.year -= 1;  
  297.         } else {  
  298.             mShowDate.month -= 1;  
  299.         }  
  300.         update();  
  301.     }  
  302.   
  303.     // 从右往左划,下一个月  
  304.     public void rightSlide() {  
  305.         if (mShowDate.month == 12) {  
  306.             mShowDate.month = 1;  
  307.             mShowDate.year += 1;  
  308.         } else {  
  309.             mShowDate.month += 1;  
  310.         }  
  311.         update();  
  312.     }  
  313.   
  314.     public void update() {  
  315.         fillDate();  
  316.         invalidate();  
  317.     }  
  318.   
  319. }  

  

/CustomCalendarView/src/com/xiaowu/calendar/DateUtil.java

[java] view plaincopy在CODE上查看代码片派生到我的代码片
  1. package com.xiaowu.calendar;  
  2.   
  3. import android.annotation.SuppressLint;  
  4. import android.util.Log;  
  5.   
  6. import java.text.ParseException;  
  7. import java.text.SimpleDateFormat;  
  8. import java.util.Calendar;  
  9. import java.util.Date;  
  10. import java.util.GregorianCalendar;  
  11.   
  12.   
  13. public class DateUtil {  
  14.   
  15.     public static String[] weekName = { "周日""周一""周二""周三""周四""周五","周六" };  
  16.   
  17.     public static int getMonthDays(int year, int month) {  
  18.         if (month > 12) {  
  19.             month = 1;  
  20.             year += 1;  
  21.         } else if (month < 1) {  
  22.             month = 12;  
  23.             year -= 1;  
  24.         }  
  25.         int[] arr = { 312831303130313130313031 };  
  26.         int days = 0;  
  27.   
  28.         if ((year % 4 == 0 && year % 100 != 0) || year % 400 == 0) {  
  29.             arr[1] = 29// 闰年2月29天  
  30.         }  
  31.   
  32.         try {  
  33.             days = arr[month - 1];  
  34.         } catch (Exception e) {  
  35.             e.getStackTrace();  
  36.         }  
  37.   
  38.         return days;  
  39.     }  
  40.       
  41.     public static int getYear() {  
  42.         return Calendar.getInstance().get(Calendar.YEAR);  
  43.     }  
  44.   
  45.     public static int getMonth() {  
  46.         return Calendar.getInstance().get(Calendar.MONTH) + 1;  
  47.     }  
  48.   
  49.     public static int getCurrentMonthDay() {  
  50.         return Calendar.getInstance().get(Calendar.DAY_OF_MONTH);  
  51.     }  
  52.   
  53.     public static int getWeekDay() {  
  54.         return Calendar.getInstance().get(Calendar.DAY_OF_WEEK);  
  55.     }  
  56.   
  57.     public static int getHour() {  
  58.         return Calendar.getInstance().get(Calendar.HOUR_OF_DAY);  
  59.     }  
  60.     public static int getMinute() {  
  61.         return Calendar.getInstance().get(Calendar.MINUTE);  
  62.     }  
  63.     public static CustomDate getNextSunday() {  
  64.           
  65.         Calendar c = Calendar.getInstance();  
  66.         c.add(Calendar.DATE, 7 - getWeekDay()+1);  
  67.         CustomDate date = new CustomDate(c.get(Calendar.YEAR),  
  68.                 c.get(Calendar.MONTH)+1, c.get(Calendar.DAY_OF_MONTH));  
  69.         return date;  
  70.     }  
  71.   
  72.     public static int[] getWeekSunday(int year, int month, int day, int pervious) {  
  73.         int[] time = new int[3];  
  74.         Calendar c = Calendar.getInstance();  
  75.         c.set(Calendar.YEAR, year);  
  76.         c.set(Calendar.MONTH, month);  
  77.         c.set(Calendar.DAY_OF_MONTH, day);  
  78.         c.add(Calendar.DAY_OF_MONTH, pervious);  
  79.         time[0] = c.get(Calendar.YEAR);  
  80.         time[1] = c.get(Calendar.MONTH )+1;  
  81.         time[2] = c.get(Calendar.DAY_OF_MONTH);  
  82.         return time;  
  83.   
  84.     }  
  85.   
  86.     public static int getWeekDayFromDate(int year, int month) {  
  87.         Calendar cal = Calendar.getInstance();  
  88.         cal.setTime(getDateFromString(year, month));  
  89.         int week_index = cal.get(Calendar.DAY_OF_WEEK) - 1;  
  90.         if (week_index < 0) {  
  91.             week_index = 0;  
  92.         }  
  93.         return week_index;  
  94.     }  
  95.   
  96.     @SuppressLint("SimpleDateFormat")  
  97.     public static Date getDateFromString(int year, int month) {  
  98.         String dateString = year + "-" + (month > 9 ? month : ("0" + month))  
  99.                 + "-01";  
  100.         Date date = null;  
  101.         try {  
  102.             SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");  
  103.             date = sdf.parse(dateString);  
  104.         } catch (ParseException e) {  
  105.             System.out.println(e.getMessage());  
  106.         }  
  107.         return date;  
  108.     }  
  109.     public static boolean isToday(CustomDate date){  
  110.         return(date.year == DateUtil.getYear() &&  
  111.                 date.month == DateUtil.getMonth()   
  112.                 && date.day == DateUtil.getCurrentMonthDay());  
  113.     }  
  114.       
  115.     public static boolean isCurrentMonth(CustomDate date){  
  116.         return(date.year == DateUtil.getYear() &&  
  117.                 date.month == DateUtil.getMonth());  
  118.     }  
  119. }  


/CustomCalendarView/src/com/xiaowu/calendar/CustomDate.java、

[java] view plaincopy在CODE上查看代码片派生到我的代码片
  1. package com.xiaowu.calendar;  
  2.   
  3. import java.io.Serializable;  
  4. public class CustomDate implements Serializable{  
  5.       
  6.       
  7.     private static final long serialVersionUID = 1L;  
  8.     public int year;  
  9.     public int month;  
  10.     public int day;  
  11.     public int week;  
  12.       
  13.     public CustomDate(int year,int month,int day){  
  14.         if(month > 12){  
  15.             month = 1;  
  16.             year++;  
  17.         }else if(month <1){  
  18.             month = 12;  
  19.             year--;  
  20.         }  
  21.         this.year = year;  
  22.         this.month = month;  
  23.         this.day = day;  
  24.     }  
  25.       
  26.     public CustomDate(){  
  27.         this.year = DateUtil.getYear();  
  28.         this.month = DateUtil.getMonth();  
  29.         this.day = DateUtil.getCurrentMonthDay();  
  30.     }  
  31.       
  32.     public static CustomDate modifiDayForObject(CustomDate date,int day){  
  33.         CustomDate modifiDate = new CustomDate(date.year,date.month,day);  
  34.         return modifiDate;  
  35.     }  
  36.     @Override  
  37.     public String toString() {  
  38.         return year+"-"+month+"-"+day;  
  39.     }  
  40.   
  41.     public int getYear() {  
  42.         return year;  
  43.     }  
  44.   
  45.     public void setYear(int year) {  
  46.         this.year = year;  
  47.     }  
  48.   
  49.     public int getMonth() {  
  50.         return month;  
  51.     }  
  52.   
  53.     public void setMonth(int month) {  
  54.         this.month = month;  
  55.     }  
  56.   
  57.     public int getDay() {  
  58.         return day;  
  59.     }  
  60.   
  61.     public void setDay(int day) {  
  62.         this.day = day;  
  63.     }  
  64.   
  65.     public int getWeek() {  
  66.         return week;  
  67.     }  
  68.   
  69.     public void setWeek(int week) {  
  70.         this.week = week;  
  71.     }  
  72.   
  73. }  



  所有绘制的操作在onDraw方面里实现,我这里定于了一个组对象Row、单元格元素Cell,通过Row[row].cell[col]来确定一个单元格,每次调用invalidate重绘视图。

接着,我们有一个需求需要左右切换,我们选用最熟悉的ViewPager,但这里有个问题,怎么实现无限循环呢,

这里我们传入一个日历卡数组,让ViewPager循环复用这几个日历卡,避免消耗内存。

/CustomCalendarView/src/com/xiaowu/calendar/CalendarViewAdapter.java

[java] view plaincopy在CODE上查看代码片派生到我的代码片
  1. package com.xiaowu.calendar;  
  2.   
  3. import android.support.v4.view.PagerAdapter;  
  4. import android.support.v4.view.ViewPager;  
  5. import android.view.View;  
  6. import android.view.ViewGroup;  
  7.   
  8. public class CalendarViewAdapter<V extends View> extends PagerAdapter {  
  9.     public static final String TAG = "CalendarViewAdapter";  
  10.     private V[] views;  
  11.   
  12.     public CalendarViewAdapter(V[] views) {  
  13.         super();  
  14.         this.views = views;  
  15.     }  
  16.   
  17.       
  18.     @Override  
  19.     public Object instantiateItem(ViewGroup container, int position) {  
  20.               
  21.         if (((ViewPager) container).getChildCount() == views.length) {  
  22.             ((ViewPager) container).removeView(views[position % views.length]);  
  23.         }  
  24.           
  25.         ((ViewPager) container).addView(views[position % views.length], 0);  
  26.         return views[position % views.length];  
  27.     }  
  28.   
  29.     @Override  
  30.     public int getCount() {  
  31.         return Integer.MAX_VALUE;  
  32.     }  
  33.   
  34.     @Override  
  35.     public boolean isViewFromObject(View view, Object object) {  
  36.         return view == ((View) object);  
  37.     }  
  38.   
  39.     @Override  
  40.     public void destroyItem(ViewGroup container, int position, Object object) {  
  41.         ((ViewPager) container).removeView((View) container);  
  42.     }  
  43.       
  44.     public V[] getAllItems() {  
  45.         return views;  
  46.     }  
  47.   
  48. }  

布局文件:

[html] view plaincopy在CODE上查看代码片派生到我的代码片
  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  
  3.     xmlns:tools="http://schemas.android.com/tools"  
  4.     android:layout_width="match_parent"  
  5.     android:layout_height="match_parent"  
  6.     android:background="@color/white"  
  7.     android:orientation="vertical" >  
  8.   
  9.     <RelativeLayout  
  10.         android:layout_width="match_parent"  
  11.         android:layout_height="50dp"  
  12.         android:background="#f6f1ea"  
  13.          >  
  14.   
  15.         <ImageButton  
  16.             android:id="@+id/btnPreMonth"  
  17.             android:layout_width="wrap_content"  
  18.             android:layout_height="wrap_content"  
  19.             android:layout_centerVertical="true"  
  20.             android:layout_marginRight="33dip"  
  21.             android:layout_toLeftOf="@+id/tvCurrentMonth"  
  22.             android:background="@drawable/ic_before" />  
  23.   
  24.         <ImageButton  
  25.             android:id="@+id/btnNextMonth"  
  26.             android:layout_width="wrap_content"  
  27.             android:layout_height="wrap_content"  
  28.             android:layout_centerVertical="true"  
  29.             android:layout_marginLeft="33dip"  
  30.             android:layout_toRightOf="@+id/tvCurrentMonth"  
  31.             android:background="@drawable/ic_next" />  
  32.   
  33.         <TextView  
  34.             android:id="@+id/tvCurrentMonth"  
  35.             android:layout_width="wrap_content"  
  36.             android:layout_height="wrap_content"  
  37.             android:layout_centerInParent="true"  
  38.             android:layout_centerVertical="true"  
  39.             android:text="11月"  
  40.             android:textColor="#323232"  
  41.             android:textSize="22sp" />  
  42.   
  43.         <ImageButton  
  44.             android:id="@+id/btnClose"  
  45.             android:layout_width="wrap_content"  
  46.             android:layout_height="wrap_content"  
  47.             android:layout_alignParentRight="true"  
  48.             android:layout_centerVertical="true"  
  49.             android:layout_marginRight="15dp"  
  50.             android:background="@drawable/ic_close" />  
  51.     </RelativeLayout>  
  52.   
  53.     <LinearLayout  
  54.         android:layout_width="match_parent"  
  55.         android:layout_height="wrap_content"  
  56.         android:layout_marginTop="15dp"  
  57.         android:orientation="vertical"  
  58.          >  
  59.   
  60.         <TableLayout  
  61.             android:layout_width="match_parent"  
  62.             android:layout_height="20dip"  
  63.             android:layout_marginBottom="2dip"  
  64.             android:layout_marginTop="2dip" >  
  65.   
  66.             <TableRow>  
  67.   
  68.                 <TextView  
  69.                     style="@style/dateStyle"  
  70.                     android:text="@string/sunday"  
  71.                     android:textColor="@color/canlendar_text_color" />  
  72.   
  73.                 <TextView  
  74.                     style="@style/dateStyle"  
  75.                     android:text="@string/monday"  
  76.                     android:textColor="@color/canlendar_text_color" />  
  77.                 <TextView  
  78.                     style="@style/dateStyle"  
  79.                     android:text="@string/thesday"  
  80.                     android:textColor="@color/canlendar_text_color" />  
  81.   
  82.                 <TextView  
  83.                     style="@style/dateStyle"  
  84.                     android:text="@string/wednesday"  
  85.                     android:textColor="@color/canlendar_text_color" />  
  86.   
  87.                 <TextView  
  88.                     style="@style/dateStyle"  
  89.                     android:text="@string/thursday"  
  90.                     android:textColor="@color/canlendar_text_color" />  
  91.   
  92.                 <TextView  
  93.                     style="@style/dateStyle"  
  94.                     android:text="@string/friday"  
  95.                     android:textColor="@color/canlendar_text_color" />  
  96.   
  97.                 <TextView  
  98.                     style="@style/dateStyle"  
  99.                     android:text="@string/saturday"  
  100.                     android:textColor="@color/canlendar_text_color" />  
  101.             </TableRow>  
  102.         </TableLayout>  
  103.     </LinearLayout>  
  104.   
  105.     <LinearLayout  
  106.         android:layout_width="match_parent"  
  107.         android:layout_height="0dp"  
  108.         android:orientation="vertical"   
  109.         android:layout_weight="1"  
  110.         android:layout_marginTop="15dp">  
  111.   
  112.         <android.support.v4.view.ViewPager  
  113.             android:id="@+id/vp_calendar"  
  114.             android:layout_width="match_parent"  
  115.             android:layout_height="wrap_content"  
  116.             android:layout_gravity="center"  
  117.             android:background="@color/white" >  
  118.         </android.support.v4.view.ViewPager>  
  119.     </LinearLayout>  
  120.   
  121. </LinearLayout>  


/CustomCalendarView/src/com/xiaowu/calendar/MainActivity.java

[java] view plaincopy在CODE上查看代码片派生到我的代码片
  1. package com.xiaowu.calendar;  
  2.   
  3.   
  4. import android.app.Activity;  
  5. import android.os.Bundle;  
  6. import android.support.v4.view.ViewPager;  
  7. import android.support.v4.view.ViewPager.OnPageChangeListener;  
  8. import android.view.View;  
  9. import android.view.View.OnClickListener;  
  10. import android.view.Window;  
  11. import android.widget.ImageButton;  
  12. import android.widget.TextView;  
  13.   
  14. import com.xiaowu.calendar.CalendarCard.OnCellClickListener;  
  15.   
  16. public class MainActivity extends Activity implements OnClickListener, OnCellClickListener{  
  17.     private ViewPager mViewPager;  
  18.     private int mCurrentIndex = 498;  
  19.     private CalendarCard[] mShowViews;  
  20.     private CalendarViewAdapter<CalendarCard> adapter;  
  21.     private SildeDirection mDirection = SildeDirection.NO_SILDE;  
  22.     enum SildeDirection {  
  23.         RIGHT, LEFT, NO_SILDE;  
  24.     }  
  25.       
  26.     private ImageButton preImgBtn, nextImgBtn;  
  27.     private TextView monthText;  
  28.     private ImageButton closeImgBtn;  
  29.   
  30.     @Override  
  31.     protected void onCreate(Bundle savedInstanceState) {  
  32.         super.onCreate(savedInstanceState);  
  33.         requestWindowFeature(Window.FEATURE_NO_TITLE);  
  34.         setContentView(R.layout.activity_main);  
  35.         mViewPager = (ViewPager) this.findViewById(R.id.vp_calendar);  
  36.         preImgBtn = (ImageButton) this.findViewById(R.id.btnPreMonth);  
  37.         nextImgBtn = (ImageButton) this.findViewById(R.id.btnNextMonth);  
  38.         monthText = (TextView) this.findViewById(R.id.tvCurrentMonth);  
  39.         closeImgBtn = (ImageButton) this.findViewById(R.id.btnClose);  
  40.         preImgBtn.setOnClickListener(this);  
  41.         nextImgBtn.setOnClickListener(this);  
  42.         closeImgBtn.setOnClickListener(this);  
  43.           
  44.         CalendarCard[] views = new CalendarCard[3];  
  45.         for (int i = 0; i < 3; i++) {  
  46.             views[i] = new CalendarCard(thisthis);  
  47.         }  
  48.         adapter = new CalendarViewAdapter<>(views);  
  49.         setViewPager();  
  50.   
  51.     }  
  52.   
  53.     private void setViewPager() {  
  54.         mViewPager.setAdapter(adapter);  
  55.         mViewPager.setCurrentItem(498);  
  56.         mViewPager.setOnPageChangeListener(new OnPageChangeListener() {  
  57.               
  58.             @Override  
  59.             public void onPageSelected(int position) {  
  60.                 measureDirection(position);  
  61.                 updateCalendarView(position);                 
  62.             }  
  63.               
  64.             @Override  
  65.             public void onPageScrolled(int arg0, float arg1, int arg2) {  
  66.                   
  67.             }  
  68.               
  69.             @Override  
  70.             public void onPageScrollStateChanged(int arg0) {  
  71.                   
  72.             }  
  73.         });  
  74.     }  
  75.   
  76.     @Override  
  77.     public void onClick(View v) {  
  78.         switch (v.getId()) {  
  79.         case R.id.btnPreMonth:  
  80.             mViewPager.setCurrentItem(mViewPager.getCurrentItem() - 1);  
  81.             break;  
  82.         case R.id.btnNextMonth:  
  83.             mViewPager.setCurrentItem(mViewPager.getCurrentItem() + 1);  
  84.             break;  
  85.         case R.id.btnClose:  
  86.             finish();  
  87.             break;  
  88.         default:  
  89.             break;  
  90.         }  
  91.     }  
  92.   
  93.     @Override  
  94.     public void clickDate(CustomDate date) {  
  95.           
  96.     }  
  97.   
  98.     @Override  
  99.     public void changeDate(CustomDate date) {  
  100.         monthText.setText(date.month + "月");  
  101.     }  
  102.   
  103.     /** 
  104.      * 计算方向 
  105.      *  
  106.      * @param arg0 
  107.      */  
  108.     private void measureDirection(int arg0) {  
  109.   
  110.         if (arg0 > mCurrentIndex) {  
  111.             mDirection = SildeDirection.RIGHT;  
  112.   
  113.         } else if (arg0 < mCurrentIndex) {  
  114.             mDirection = SildeDirection.LEFT;  
  115.         }  
  116.         mCurrentIndex = arg0;  
  117.     }  
  118.   
  119.     // 更新日历视图  
  120.     private void updateCalendarView(int arg0) {  
  121.         mShowViews = adapter.getAllItems();  
  122.         if (mDirection == SildeDirection.RIGHT) {  
  123.             mShowViews[arg0 % mShowViews.length].rightSlide();  
  124.         } else if (mDirection == SildeDirection.LEFT) {  
  125.             mShowViews[arg0 % mShowViews.length].leftSlide();  
  126.         }  
  127.         mDirection = SildeDirection.NO_SILDE;  
  128.     }  
  129.   
  130.   
  131.       
  132. }  


用到的资源:

/CustomCalendarView/res/values/color.xml

[html] view plaincopy在CODE上查看代码片派生到我的代码片
  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <resources>  
  3.     <color name="white">#ffffff</color>  
  4.      <color name="canlendar_text_color">#323232</color>  
  5. </resources>  


/CustomCalendarView/res/values/strings.xml

[html] view plaincopy在CODE上查看代码片派生到我的代码片
  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <resources>  
  3.   
  4.     <string name="app_name">CustomCalendarView</string>  
  5.     <string name="hello_world">Hello world!</string>  
  6.     <string name="action_settings">Settings</string>  
  7.   
  8.       
  9.     <string name="sunday"></string>  
  10.     <string name="monday"></string>  
  11.     <string name="thesday"></string>  
  12.     <string name="wednesday"></string>  
  13.     <string name="thursday"></string>  
  14.     <string name="friday"></string>  
  15.     <string name="saturday"></string>  
  16.       
  17. </resources>  

/CustomCalendarView/res/values/styles.xml

[html] view plaincopy在CODE上查看代码片派生到我的代码片
  1. <resources>  
  2.   
  3.     <!--  
  4.         Base application theme, dependent on API level. This theme is replaced  
  5.         by AppBaseTheme from res/values-vXX/styles.xml on newer devices.  
  6.     -->  
  7.     <style name="AppBaseTheme" parent="android:Theme.Light">  
  8.         <!--  
  9.             Theme customizations available in newer API levels can go in  
  10.             res/values-vXX/styles.xml, while customizations related to  
  11.             backward-compatibility can go here.  
  12.         -->  
  13.     </style>  
  14.   
  15.     <!-- Application theme. -->  
  16.     <style name="AppTheme" parent="AppBaseTheme">  
  17.         <!-- All customizations that are NOT specific to a particular API-level can go here. -->  
  18.     </style>  
  19.       
  20.     <style name="dateStyle">  
  21.         <item name="android:layout_width">fill_parent</item>  
  22.         <item name="android:layout_height">fill_parent</item>  
  23.         <item name="android:layout_weight">1</item>  
  24.         <item name="android:gravity">center</item>  
  25.         <item name="android:textSize">16sp</item>  
  26.     </style>  
  27.   
  28. </resources>  
0 0
原创粉丝点击