«

Android UI-自定义日历控件

时间:2024-3-2 17:27     作者:韩俊     分类: Android


Android UI-自定义日历控件


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


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


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

我们会有以下效果:

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

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

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

直接上代码:

[java] view
plaincopy

package com.xiaowu.calendar;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewConfiguration;

/**

  • 自定义日历卡
  • @author wuwenjie
  • */
    public class CalendarCard extends View {

    private static final int TOTAL_COL = 7; // 7列
    private static final int TOTAL_ROW = 6; // 6行

    private Paint mCirclePaint; // 绘制圆形的画笔
    private Paint mTextPaint; // 绘制文本的画笔
    private int mViewWidth; // 视图的宽度
    private int mViewHeight; // 视图的高度
    private int mCellSpace; // 单元格间距
    private Row rows[] = new Row[TOTAL_ROW]; // 行数组,每个元素代表一行
    private static CustomDate mShowDate; // 自定义的日期,包括year,month,day
    private OnCellClickListener mCellClickListener; // 单元格点击回调事件
    private int touchSlop; //
    private boolean callBackCellSpace;

    private Cell mClickCell;
    private float mDownX;
    private float mDownY;

    /**

    • 单元格点击的回调接口
    • @author wuwenjie
    • */
      public interface OnCellClickListener {
      void clickDate(CustomDate date); // 回调点击的日期

      void changeDate(CustomDate date); // 回调滑动ViewPager改变的日期
      }

    public CalendarCard(Context context, AttributeSet attrs, int defStyleAttr) {
    super(context, attrs, defStyleAttr);
    init(context);
    }

    public CalendarCard(Context context, AttributeSet attrs) {
    super(context, attrs);
    init(context);
    }

    public CalendarCard(Context context) {
    super(context);
    init(context);
    }

    public CalendarCard(Context context, OnCellClickListener listener) {
    super(context);
    this.mCellClickListener = listener;
    init(context);
    }

    private void init(Context context) {
    mTextPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
    mCirclePaint = new Paint(Paint.ANTI_ALIAS_FLAG);
    mCirclePaint.setStyle(Paint.Style.FILL);
    mCirclePaint.setColor(Color.parseColor("#F24949")); // 红色圆形
    touchSlop = ViewConfiguration.get(context).getScaledTouchSlop();

    initDate();  

    }

    private void initDate() {
    mShowDate = new CustomDate();
    fillDate();//
    }

    private void fillDate() {
    int monthDay = DateUtil.getCurrentMonthDay(); // 今天
    int lastMonthDays = DateUtil.getMonthDays(mShowDate.year,
    mShowDate.month - 1); // 上个月的天数
    int currentMonthDays = DateUtil.getMonthDays(mShowDate.year,
    mShowDate.month); // 当前月的天数
    int firstDayWeek = DateUtil.getWeekDayFromDate(mShowDate.year,
    mShowDate.month);
    boolean isCurrentMonth = false;
    if (DateUtil.isCurrentMonth(mShowDate)) {
    isCurrentMonth = true;
    }
    int day = 0;
    for (int j = 0; j < TOTAL_ROW; j++) {
    rows[j] = new Row(j);
    for (int i = 0; i < TOTAL_COL; i++) {
    int position = i + j * TOTAL_COL; // 单元格位置
    // 这个月的
    if (position >= firstDayWeek
    && position < firstDayWeek + currentMonthDays) {
    day++;
    rows[j].cells[i] = new Cell(CustomDate.modifiDayForObject(
    mShowDate, day), State.CURRENT_MONTH_DAY, i, j);
    // 今天
    if (isCurrentMonth && day == monthDay ) {
    CustomDate date = CustomDate.modifiDayForObject(mShowDate, day);
    rows[j].cells[i] = new Cell(date, State.TODAY, i, j);
    }

                if (isCurrentMonth &amp;&amp; day &gt; monthDay) { // 如果比这个月的今天要大,表示还没到  
                    rows[j].cells[i] = new Cell(  
                            CustomDate.modifiDayForObject(mShowDate, day),  
                            State.UNREACH_DAY, i, j);  
                }  
    
                // 过去一个月  
            } else if (position &lt; firstDayWeek) {  
                rows[j].cells[i] = new Cell(new CustomDate(mShowDate.year,  
                        mShowDate.month - 1, lastMonthDays  
                                - (firstDayWeek - position - 1)),  
                        State.PAST_MONTH_DAY, i, j);  
                // 下个月  
            } else if (position &gt;= firstDayWeek &#43; currentMonthDays) {  
                rows[j].cells[i] = new Cell((new CustomDate(mShowDate.year,  
                        mShowDate.month &#43; 1, position - firstDayWeek  
                                - currentMonthDays &#43; 1)),  
                        State.NEXT_MONTH_DAY, i, j);  
            }  
        }  
    }  
    mCellClickListener.changeDate(mShowDate);  

    }

    @Override
    protected void onDraw(Canvas canvas) {
    super.onDraw(canvas);
    for (int i = 0; i < TOTAL_ROW; i++) {
    if (rows[i] != null) {
    rows[i].drawCells(canvas);
    }
    }
    }

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
    super.onSizeChanged(w, h, oldw, oldh);
    mViewWidth = w;
    mViewHeight = h;
    mCellSpace = Math.min(mViewHeight / TOTAL_ROW, mViewWidth / TOTAL_COL);
    if (!callBackCellSpace) {
    callBackCellSpace = true;
    }
    mTextPaint.setTextSize(mCellSpace / 3);
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
    switch (event.getAction()) {
    case MotionEvent.ACTION_DOWN:
    mDownX = event.getX();
    mDownY = event.getY();
    break;
    case MotionEvent.ACTION_UP:
    float disX = event.getX() - mDownX;
    float disY = event.getY() - mDownY;
    if (Math.abs(disX) < touchSlop && Math.abs(disY) < touchSlop) {
    int col = (int) (mDownX / mCellSpace);
    int row = (int) (mDownY / mCellSpace);
    measureClickCell(col, row);
    }
    break;
    default:
    break;
    }

    return true;  

    }

    /**

    • 计算点击的单元格
    • @param col
    • @param row
      */
      private void measureClickCell(int col, int row) {
      if (col >= TOTAL_COL || row >= TOTAL_ROW)
      return;
      if (mClickCell != null) {
      rows[mClickCell.j].cells[mClickCell.i] = mClickCell;
      }
      if (rows[row] != null) {
      mClickCell = new Cell(rows[row].cells[col].date,
      rows[row].cells[col].state, rows[row].cells[col].i,
      rows[row].cells[col].j);

      CustomDate date = rows[row].cells[col].date;  
      date.week = col;  
      mCellClickListener.clickDate(date);  
      
      // 刷新界面  
      update();  

      }
      }

    /**

    • 组元素
    • @author wuwenjie
    • */
      class Row {
      public int j;

      Row(int j) {
      this.j = j;
      }

      public Cell[] cells = new Cell[TOTAL_COL];

      // 绘制单元格
      public void drawCells(Canvas canvas) {
      for (int i = 0; i < cells.length; i++) {
      if (cells[i] != null) {
      cells[i].drawSelf(canvas);
      }
      }
      }

    }

    /**

    • 单元格元素
    • @author wuwenjie
    • */
      class Cell {
      public CustomDate date;
      public State state;
      public int i;
      public int j;

      public Cell(CustomDate date, State state, int i, int j) {
      super();
      this.date = date;
      this.state = state;
      this.i = i;
      this.j = j;
      }

      public void drawSelf(Canvas canvas) {
      switch (state) {
      case TODAY: // 今天
      mTextPaint.setColor(Color.parseColor("#fffffe"));
      canvas.drawCircle((float) (mCellSpace (i + 0.5)),
      (float) ((j + 0.5)
      mCellSpace), mCellSpace / 3,
      mCirclePaint);
      break;
      case CURRENT_MONTH_DAY: // 当前月日期
      mTextPaint.setColor(Color.BLACK);
      break;
      case PAST_MONTH_DAY: // 过去一个月
      case NEXT_MONTH_DAY: // 下一个月
      mTextPaint.setColor(Color.parseColor("#fffffe"));
      break;
      case UNREACH_DAY: // 还未到的天
      mTextPaint.setColor(Color.GRAY);
      break;
      default:
      break;
      }
      // 绘制文字
      String content = date.day + "";
      canvas.drawText(content,
      (float) ((i + 0.5) * mCellSpace - mTextPaint
      .measureText(content) / 2), (float) ((j + 0.7)

      • mCellSpace - mTextPaint
        .measureText(content, 0, 1) / 2), mTextPaint);
        }
        }

    /**

    • @author wuwenjie 单元格的状态 当前月日期,过去的月的日期,下个月的日期
      */
      enum State {
      TODAY,CURRENT_MONTH_DAY, PAST_MONTH_DAY, NEXT_MONTH_DAY, UNREACH_DAY;
      }

    // 从左往右划,上一个月
    public void leftSlide() {
    if (mShowDate.month == 1) {
    mShowDate.month = 12;
    mShowDate.year -= 1;
    } else {
    mShowDate.month -= 1;
    }
    update();
    }

    // 从右往左划,下一个月
    public void rightSlide() {
    if (mShowDate.month == 12) {
    mShowDate.month = 1;
    mShowDate.year += 1;
    } else {
    mShowDate.month += 1;
    }
    update();
    }

    public void update() {
    fillDate();
    invalidate();
    }

}

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

[java] view
plaincopy

package com.xiaowu.calendar;

import android.annotation.SuppressLint;
import android.util.Log;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;

public class DateUtil {

public static String[] weekName = { &quot;周日&quot;, &quot;周一&quot;, &quot;周二&quot;, &quot;周三&quot;, &quot;周四&quot;, &quot;周五&quot;,&quot;周六&quot; };  

public static int getMonthDays(int year, int month) {  
    if (month &gt; 12) {  
        month = 1;  
        year &#43;= 1;  
    } else if (month &lt; 1) {  
        month = 12;  
        year -= 1;  
    }  
    int[] arr = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };  
    int days = 0;  

    if ((year % 4 == 0 &amp;&amp; year % 100 != 0) || year % 400 == 0) {  
        arr[1] = 29; // 闰年2月29天  
    }  

    try {  
        days = arr[month - 1];  
    } catch (Exception e) {  
        e.getStackTrace();  
    }  

    return days;  
}  

public static int getYear() {  
    return Calendar.getInstance().get(Calendar.YEAR);  
}  

public static int getMonth() {  
    return Calendar.getInstance().get(Calendar.MONTH) &#43; 1;  
}  

public static int getCurrentMonthDay() {  
    return Calendar.getInstance().get(Calendar.DAY_OF_MONTH);  
}  

public static int getWeekDay() {  
    return Calendar.getInstance().get(Calendar.DAY_OF_WEEK);  
}  

public static int getHour() {  
    return Calendar.getInstance().get(Calendar.HOUR_OF_DAY);  
}  
public static int getMinute() {  
    return Calendar.getInstance().get(Calendar.MINUTE);  
}  
public static CustomDate getNextSunday() {  

    Calendar c = Calendar.getInstance();  
    c.add(Calendar.DATE, 7 - getWeekDay()&#43;1);  
    CustomDate date = new CustomDate(c.get(Calendar.YEAR),  
            c.get(Calendar.MONTH)&#43;1, c.get(Calendar.DAY_OF_MONTH));  
    return date;  
}  

public static int[] getWeekSunday(int year, int month, int day, int pervious) {  
    int[] time = new int[3];  
    Calendar c = Calendar.getInstance();  
    c.set(Calendar.YEAR, year);  
    c.set(Calendar.MONTH, month);  
    c.set(Calendar.DAY_OF_MONTH, day);  
    c.add(Calendar.DAY_OF_MONTH, pervious);  
    time[0] = c.get(Calendar.YEAR);  
    time[1] = c.get(Calendar.MONTH )&#43;1;  
    time[2] = c.get(Calendar.DAY_OF_MONTH);  
    return time;  

}  

public static int getWeekDayFromDate(int year, int month) {  
    Calendar cal = Calendar.getInstance();  
    cal.setTime(getDateFromString(year, month));  
    int week_index = cal.get(Calendar.DAY_OF_WEEK) - 1;  
    if (week_index &lt; 0) {  
        week_index = 0;  
    }  
    return week_index;  
}  

@SuppressLint(&quot;SimpleDateFormat&quot;)  
public static Date getDateFromString(int year, int month) {  
    String dateString = year &#43; &quot;-&quot; &#43; (month &gt; 9 ? month : (&quot;0&quot; &#43; month))  
            &#43; &quot;-01&quot;;  
    Date date = null;  
    try {  
        SimpleDateFormat sdf = new SimpleDateFormat(&quot;yyyy-MM-dd&quot;);  
        date = sdf.parse(dateString);  
    } catch (ParseException e) {  
        System.out.println(e.getMessage());  
    }  
    return date;  
}  
public static boolean isToday(CustomDate date){  
    return(date.year == DateUtil.getYear() &amp;&amp;  
            date.month == DateUtil.getMonth()   
            &amp;&amp; date.day == DateUtil.getCurrentMonthDay());  
}  

public static boolean isCurrentMonth(CustomDate date){  
    return(date.year == DateUtil.getYear() &amp;&amp;  
            date.month == DateUtil.getMonth());  
}  

}



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

[java] view
plaincopy

package com.xiaowu.calendar;

import java.io.Serializable;
public class CustomDate implements Serializable{

private static final long serialVersionUID = 1L;  
public int year;  
public int month;  
public int day;  
public int week;  

public CustomDate(int year,int month,int day){  
    if(month &gt; 12){  
        month = 1;  
        year&#43;&#43;;  
    }else if(month &lt;1){  
        month = 12;  
        year--;  
    }  
    this.year = year;  
    this.month = month;  
    this.day = day;  
}  

public CustomDate(){  
    this.year = DateUtil.getYear();  
    this.month = DateUtil.getMonth();  
    this.day = DateUtil.getCurrentMonthDay();  
}  

public static CustomDate modifiDayForObject(CustomDate date,int day){  
    CustomDate modifiDate = new CustomDate(date.year,date.month,day);  
    return modifiDate;  
}  
@Override  
public String toString() {  
    return year&#43;&quot;-&quot;&#43;month&#43;&quot;-&quot;&#43;day;  
}  

public int getYear() {  
    return year;  
}  

public void setYear(int year) {  
    this.year = year;  
}  

public int getMonth() {  
    return month;  
}  

public void setMonth(int month) {  
    this.month = month;  
}  

public int getDay() {  
    return day;  
}  

public void setDay(int day) {  
    this.day = day;  
}  

public int getWeek() {  
    return week;  
}  

public void setWeek(int week) {  
    this.week = week;  
}  

}





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

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

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

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

[java] view
plaincopy

package com.xiaowu.calendar;

import android.support.v4.view.PagerAdapter;
import android.support.v4.view.ViewPager;
import android.view.View;
import android.view.ViewGroup;

public class CalendarViewAdapter<V extends View> extends PagerAdapter {
public static final String TAG = "CalendarViewAdapter";
private V[] views;

public CalendarViewAdapter(V[] views) {  
    super();  
    this.views = views;  
}  

@Override  
public Object instantiateItem(ViewGroup container, int position) {  

    if (((ViewPager) container).getChildCount() == views.length) {  
        ((ViewPager) container).removeView(views[position % views.length]);  
    }  

    ((ViewPager) container).addView(views[position % views.length], 0);  
    return views[position % views.length];  
}  

@Override  
public int getCount() {  
    return Integer.MAX_VALUE;  
}  

@Override  
public boolean isViewFromObject(View view, Object object) {  
    return view == ((View) object);  
}  

@Override  
public void destroyItem(ViewGroup container, int position, Object object) {  
    ((ViewPager) container).removeView((View) container);  
}  

public V[] getAllItems() {  
    return views;  
}  

}



布局文件:

[html] view
plaincopy

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android&quot;
xmlns:tools="http://schemas.android.com/tools&quot;
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/white"
android:orientation="vertical" >

&lt;RelativeLayout  
    android:layout_width=&quot;match_parent&quot;  
    android:layout_height=&quot;50dp&quot;  
    android:background=&quot;#f6f1ea&quot;  
     &gt;  

    &lt;ImageButton  
        android:id=&quot;@&#43;id/btnPreMonth&quot;  
        android:layout_width=&quot;wrap_content&quot;  
        android:layout_height=&quot;wrap_content&quot;  
        android:layout_centerVertical=&quot;true&quot;  
        android:layout_marginRight=&quot;33dip&quot;  
        android:layout_toLeftOf=&quot;@&#43;id/tvCurrentMonth&quot;  
        android:background=&quot;@drawable/ic_before&quot; /&gt;  

    &lt;ImageButton  
        android:id=&quot;@&#43;id/btnNextMonth&quot;  
        android:layout_width=&quot;wrap_content&quot;  
        android:layout_height=&quot;wrap_content&quot;  
        android:layout_centerVertical=&quot;true&quot;  
        android:layout_marginLeft=&quot;33dip&quot;  
        android:layout_toRightOf=&quot;@&#43;id/tvCurrentMonth&quot;  
        android:background=&quot;@drawable/ic_next&quot; /&gt;  

    &lt;TextView  
        android:id=&quot;@&#43;id/tvCurrentMonth&quot;  
        android:layout_width=&quot;wrap_content&quot;  
        android:layout_height=&quot;wrap_content&quot;  
        android:layout_centerInParent=&quot;true&quot;  
        android:layout_centerVertical=&quot;true&quot;  
        android:text=&quot;11月&quot;  
        android:textColor=&quot;#323232&quot;  
        android:textSize=&quot;22sp&quot; /&gt;  

    &lt;ImageButton  
        android:id=&quot;@&#43;id/btnClose&quot;  
        android:layout_width=&quot;wrap_content&quot;  
        android:layout_height=&quot;wrap_content&quot;  
        android:layout_alignParentRight=&quot;true&quot;  
        android:layout_centerVertical=&quot;true&quot;  
        android:layout_marginRight=&quot;15dp&quot;  
        android:background=&quot;@drawable/ic_close&quot; /&gt;  
&lt;/RelativeLayout&gt;  

&lt;LinearLayout  
    android:layout_width=&quot;match_parent&quot;  
    android:layout_height=&quot;wrap_content&quot;  
    android:layout_marginTop=&quot;15dp&quot;  
    android:orientation=&quot;vertical&quot;  
     &gt;  

    &lt;TableLayout  
        android:layout_width=&quot;match_parent&quot;  
        android:layout_height=&quot;20dip&quot;  
        android:layout_marginBottom=&quot;2dip&quot;  
        android:layout_marginTop=&quot;2dip&quot; &gt;  

        &lt;TableRow&gt;  

            &lt;TextView  
                style=&quot;@style/dateStyle&quot;  
                android:text=&quot;@string/sunday&quot;  
                android:textColor=&quot;@color/canlendar_text_color&quot; /&gt;  

            &lt;TextView  
                style=&quot;@style/dateStyle&quot;  
                android:text=&quot;@string/monday&quot;  
                android:textColor=&quot;@color/canlendar_text_color&quot; /&gt;  
            &lt;TextView  
                style=&quot;@style/dateStyle&quot;  
                android:text=&quot;@string/thesday&quot;  
                android:textColor=&quot;@color/canlendar_text_color&quot; /&gt;  

            &lt;TextView  
                style=&quot;@style/dateStyle&quot;  
                android:text=&quot;@string/wednesday&quot;  
                android:textColor=&quot;@color/canlendar_text_color&quot; /&gt;  

            &lt;TextView  
                style=&quot;@style/dateStyle&quot;  
                android:text=&quot;@string/thursday&quot;  
                android:textColor=&quot;@color/canlendar_text_color&quot; /&gt;  

            &lt;TextView  
                style=&quot;@style/dateStyle&quot;  
                android:text=&quot;@string/friday&quot;  
                android:textColor=&quot;@color/canlendar_text_color&quot; /&gt;  

            &lt;TextView  
                style=&quot;@style/dateStyle&quot;  
                android:text=&quot;@string/saturday&quot;  
                android:textColor=&quot;@color/canlendar_text_color&quot; /&gt;  
        &lt;/TableRow&gt;  
    &lt;/TableLayout&gt;  
&lt;/LinearLayout&gt;  

&lt;LinearLayout  
    android:layout_width=&quot;match_parent&quot;  
    android:layout_height=&quot;0dp&quot;  
    android:orientation=&quot;vertical&quot;   
    android:layout_weight=&quot;1&quot;  
    android:layout_marginTop=&quot;15dp&quot;&gt;  

    &lt;android.support.v4.view.ViewPager  
        android:id=&quot;@&#43;id/vp_calendar&quot;  
        android:layout_width=&quot;match_parent&quot;  
        android:layout_height=&quot;wrap_content&quot;  
        android:layout_gravity=&quot;center&quot;  
        android:background=&quot;@color/white&quot; &gt;  
    &lt;/android.support.v4.view.ViewPager&gt;  
&lt;/LinearLayout&gt;  

</LinearLayout>




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

[java] view
plaincopy

package com.xiaowu.calendar;

import android.app.Activity;
import android.os.Bundle;
import android.support.v4.view.ViewPager;
import android.support.v4.view.ViewPager.OnPageChangeListener;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.Window;
import android.widget.ImageButton;
import android.widget.TextView;

import com.xiaowu.calendar.CalendarCard.OnCellClickListener;

public class MainActivity extends Activity implements OnClickListener, OnCellClickListener{
private ViewPager mViewPager;
private int mCurrentIndex = 498;
private CalendarCard[] mShowViews;
private CalendarViewAdapter<CalendarCard> adapter;
private SildeDirection mDirection = SildeDirection.NO_SILDE;
enum SildeDirection {
RIGHT, LEFT, NO_SILDE;
}

private ImageButton preImgBtn, nextImgBtn;  
private TextView monthText;  
private ImageButton closeImgBtn;  

@Override  
protected void onCreate(Bundle savedInstanceState) {  
    super.onCreate(savedInstanceState);  
    requestWindowFeature(Window.FEATURE_NO_TITLE);  
    setContentView(R.layout.activity_main);  
    mViewPager = (ViewPager) this.findViewById(R.id.vp_calendar);  
    preImgBtn = (ImageButton) this.findViewById(R.id.btnPreMonth);  
    nextImgBtn = (ImageButton) this.findViewById(R.id.btnNextMonth);  
    monthText = (TextView) this.findViewById(R.id.tvCurrentMonth);  
    closeImgBtn = (ImageButton) this.findViewById(R.id.btnClose);  
    preImgBtn.setOnClickListener(this);  
    nextImgBtn.setOnClickListener(this);  
    closeImgBtn.setOnClickListener(this);  

    CalendarCard[] views = new CalendarCard[3];  
    for (int i = 0; i &lt; 3; i&#43;&#43;) {  
        views[i] = new CalendarCard(this, this);  
    }  
    adapter = new CalendarViewAdapter&lt;&gt;(views);  
    setViewPager();  

}  

private void setViewPager() {  
    mViewPager.setAdapter(adapter);  
    mViewPager.setCurrentItem(498);  
    mViewPager.setOnPageChangeListener(new OnPageChangeListener() {  

        @Override  
        public void onPageSelected(int position) {  
            measureDirection(position);  
            updateCalendarView(position);                 
        }  

        @Override  
        public void onPageScrolled(int arg0, float arg1, int arg2) {  

        }  

        @Override  
        public void onPageScrollStateChanged(int arg0) {  

        }  
    });  
}  

@Override  
public void onClick(View v) {  
    switch (v.getId()) {  
    case R.id.btnPreMonth:  
        mViewPager.setCurrentItem(mViewPager.getCurrentItem() - 1);  
        break;  
    case R.id.btnNextMonth:  
        mViewPager.setCurrentItem(mViewPager.getCurrentItem() &#43; 1);  
        break;  
    case R.id.btnClose:  
        finish();  
        break;  
    default:  
        break;  
    }  
}  

@Override  
public void clickDate(CustomDate date) {  

}  

@Override  
public void changeDate(CustomDate date) {  
    monthText.setText(date.month &#43; &quot;月&quot;);  
}  

/** 
 * 计算方向 
 *  
 * @param arg0 
 */  
private void measureDirection(int arg0) {  

    if (arg0 &gt; mCurrentIndex) {  
        mDirection = SildeDirection.RIGHT;  

    } else if (arg0 &lt; mCurrentIndex) {  
        mDirection = SildeDirection.LEFT;  
    }  
    mCurrentIndex = arg0;  
}  

// 更新日历视图  
private void updateCalendarView(int arg0) {  
    mShowViews = adapter.getAllItems();  
    if (mDirection == SildeDirection.RIGHT) {  
        mShowViews[arg0 % mShowViews.length].rightSlide();  
    } else if (mDirection == SildeDirection.LEFT) {  
        mShowViews[arg0 % mShowViews.length].leftSlide();  
    }  
    mDirection = SildeDirection.NO_SILDE;  
}  

}




用到的资源:

/CustomCalendarView/res/values/color.xml

[html] view
plaincopy

<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="white">#ffffff</color>
<color name="canlendar_text_color">#323232</color>
</resources>


/CustomCalendarView/res/values/strings.xml

[html] view
plaincopy

<?xml version="1.0" encoding="utf-8"?>
<resources>

&lt;string name=&quot;app_name&quot;&gt;CustomCalendarView&lt;/string&gt;  
&lt;string name=&quot;hello_world&quot;&gt;Hello world!&lt;/string&gt;  
&lt;string name=&quot;action_settings&quot;&gt;Settings&lt;/string&gt;  

&lt;string name=&quot;sunday&quot;&gt;日&lt;/string&gt;  
&lt;string name=&quot;monday&quot;&gt;一&lt;/string&gt;  
&lt;string name=&quot;thesday&quot;&gt;二&lt;/string&gt;  
&lt;string name=&quot;wednesday&quot;&gt;三&lt;/string&gt;  
&lt;string name=&quot;thursday&quot;&gt;四&lt;/string&gt;  
&lt;string name=&quot;friday&quot;&gt;五&lt;/string&gt;  
&lt;string name=&quot;saturday&quot;&gt;六&lt;/string&gt;  

</resources>



/CustomCalendarView/res/values/styles.xml

[html] view
plaincopy

<resources>

&lt;!--  
    Base application theme, dependent on API level. This theme is replaced  
    by AppBaseTheme from res/values-vXX/styles.xml on newer devices.  
--&gt;  
&lt;style name=&quot;AppBaseTheme&quot; parent=&quot;android:Theme.Light&quot;&gt;  
    &lt;!--  
        Theme customizations available in newer API levels can go in  
        res/values-vXX/styles.xml, while customizations related to  
        backward-compatibility can go here.  
    --&gt;  
&lt;/style&gt;  

&lt;!-- Application theme. --&gt;  
&lt;style name=&quot;AppTheme&quot; parent=&quot;AppBaseTheme&quot;&gt;  
    &lt;!-- All customizations that are NOT specific to a particular API-level can go here. --&gt;  
&lt;/style&gt;  

&lt;style name=&quot;dateStyle&quot;&gt;  
    &lt;item name=&quot;android:layout_width&quot;&gt;fill_parent&lt;/item&gt;  
    &lt;item name=&quot;android:layout_height&quot;&gt;fill_parent&lt;/item&gt;  
    &lt;item name=&quot;android:layout_weight&quot;&gt;1&lt;/item&gt;  
    &lt;item name=&quot;android:gravity&quot;&gt;center&lt;/item&gt;  
    &lt;item name=&quot;android:textSize&quot;&gt;16sp&lt;/item&gt;  
&lt;/style&gt;  

</resources>




源码下载:http://download.csdn.net/detail/wwj_748/8312233


转自:http://blog.csdn.net/wwj_748/article/details/42244865

标签: android

热门推荐