android自定義日歷實現事件提醒package com.example.calendar

1.概述

android自定義日歷實現事件提醒package com.example.calendar,前段時間項目需要一個日歷提醒,需求是:可以左右無限滑動,可點擊監聽,根據事件日期在視圖中描出,右上角顯示事件個數。
在網上搜瞭很多,但是不是很滿足項目特定的需求,所以在網上的例子的基礎上自定義瞭一個,供大傢參考。

2.先上圖

這裡寫圖片描述

這裡日期是自己畫的,沒有使用GridView,使用自定義view更方便。
我們通過計算每個月的日期,然後根據計算出來的位置繪制我們的日期。這裡使用標準的6*7方格圖。
我會把註釋放在代碼裡,直接上代碼:

1.CalendarView

package com.example.calendar;

import java.util.List;

import com.example.calendar.RepayPlanInfo;
import com.example.calendar.DateUtil;

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;

public class CalendarView extends View {

    private static final String TAG = "CalendarView";

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

    private Paint BlueBgPaint, HuiseBgPaint, mCirclePaint, linePaint;
    private Paint mTextPaint, mCutTextPaint;
    private int mViewWidth;//控件寬度
    private int mViewHight;//控件高度
    private float mCellSpace, mCellwide;//方格的寬和高
    private Row rows[] = new Row[TOTAL_ROW];//行數組
    private static RepayPlanInfo mShowDate;// 自定義的單元格信息 包括year month day
    private CallBack mCallBack;// 回調
    private int touchSlop;
    private float radius;//提醒圓的半徑
    private Cell mClickCell = null;//點擊的單元格
    private float mDownX;
    private float mDownY;
    private boolean callBackCellSpace = false;
    String[] str = { "日", "一", "二", "三", "四", "五", "六" };

    public interface CallBack {

        void clickDate(RepayPlanInfo date);// 回調點擊的日期

        void onMesureCellHeight(float mCellSpace, float mCellwide);/// 回調cell的高度確定slidingDrawer高度

        void changeDate(RepayPlanInfo date);// 回調滑動viewPager改變的日期
    }

    public CalendarView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        init(context);
    }

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

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

    public CalendarView(Context context, CallBack mCallBack) {
        super(context);
        // CalendarView.style = style;
        this.mCallBack = mCallBack;
        init(context);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        //畫頂部的星期
        drawWeek(canvas);
        //畫日期單元格
        for (int i = 0; i < TOTAL_ROW; i++) {
            if (rows[i] != null)
                rows[i].drawCells(canvas);
        }
    }

    private void drawWeek(Canvas canvas) {
        for (int i = 0; i < TOTAL_COL; i++) {
            if (i == 0) {
                mTextPaint.setColor(Color.parseColor("#b1b1b1"));
            } else {
                mTextPaint.setColor(Color.parseColor("#80000000"));
            }
            canvas.drawText(str[i], (float) ((i + 0.5) * mCellSpace - mTextPaint.measureText(str[i]) / 2),
                    (float) (0.5 * mCellwide + mTextPaint.measureText(str[i]) / 2), mTextPaint);
        }
        canvas.drawLine(0, mCellwide, mViewWidth, mCellwide, linePaint);
    }

    //初始化畫筆
    private void init(Context context) {
        mTextPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        mCutTextPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        linePaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        linePaint.setTextSize(0.5f);
        linePaint.setColor(0x20000000);

        BlueBgPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        BlueBgPaint.setStyle(Paint.Style.FILL);
        BlueBgPaint.setColor(Color.parseColor("#3693fd"));

        HuiseBgPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        HuiseBgPaint.setStyle(Paint.Style.FILL);
        HuiseBgPaint.setColor(Color.parseColor("#e9e9e9"));

        mCirclePaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        mCirclePaint.setStyle(Paint.Style.FILL);
        mCirclePaint.setColor(Color.parseColor("#fa4548"));

        touchSlop = ViewConfiguration.get(context).getScaledTouchSlop();
        initDate();

    }

    private void initDate() {
        mShowDate = new RepayPlanInfo();
        //填充日期的數據
        fillDate();
    }

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
        mViewWidth = w;
        mViewHight = h;
        mCellSpace = mViewWidth / TOTAL_COL;
        radius = mCellSpace / 4;//紅色圓圈的半徑,這裡根據單元格寬度確定
        //要在第一行頂部留下畫圓的高度,所以這裡減去半徑
        mCellwide = (mViewHight - radius) / 7;
        if (!callBackCellSpace) {
            mCallBack.onMesureCellHeight(mCellSpace, mCellwide);
            callBackCellSpace = true;
        }
        mTextPaint.setTextSize(mCellSpace / 3);
        mCutTextPaint.setTextSize(mCellSpace / 6);
        mCutTextPaint.setColor(Color.parseColor("#fffffe"));

    }

    /*
     * 
     * 觸摸事件為瞭確定點擊的位置日期
     */
    @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 && event.getY() > mCellwide) {
                int col = (int) (mDownX / mCellSpace);
                int row = (int) ((mDownY - mCellwide) / mCellwide);
                measureClickCell(col, row);
            }
            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);
            rows[row].cells[col].state = State.CLICK_DAY;
            RepayPlanInfo date = rows[row].cells[col].date;
            date.week = col;
            mCallBack.clickDate(date);
            invalidate();
        }
    }

    // 組
    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);
            }

        }
    }

    // 單元格
    class Cell {
        public RepayPlanInfo date;
        public State state;
        /**
         * i = 行 j = 列
         */
        public int i;
        public int j;

        public Cell(RepayPlanInfo 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 CURRENT_MONTH_DAY:
                mTextPaint.setColor(Color.parseColor("#80000000"));
                break;
            case NEXT_MONTH_DAY:
            case PAST_MONTH_DAY:
                mTextPaint.setColor(Color.parseColor("#b1b1b1"));
                break;
            case TODAY:
                mTextPaint.setColor(Color.parseColor("#F24949"));
                break;
            case CLICK_DAY:
                mTextPaint.setColor(Color.parseColor("#fffffe"));
                canvas.drawRect((float) (mCellSpace * i), (float) (mCellwide * (j + 1) + radius / 2),
                        (float) (mCellSpace * (i + 1)), (float) (mCellwide * (j + 2) + radius / 2), BlueBgPaint);
                break;
            case REMIND_DAY:
                mTextPaint.setColor(Color.parseColor("#80000000"));
                canvas.drawRect((float) (mCellSpace * i), (float) (mCellwide * (j + 1) + radius / 2),
                        (float) (mCellSpace * (i + 1)), (float) (mCellwide * (j + 2) + radius / 2), HuiseBgPaint);

                break;
            }
            // 繪制日期文字
            String content = date.day + "";
            canvas.drawText(content, (float) ((i + 0.5) * mCellSpace - mTextPaint.measureText(content) / 2),
                    (float) ((j + 1.5) * mCellwide + mTextPaint.measureText(content, 0, 1) / 2 + radius / 2),
                    mTextPaint);

            // 繪制右上角提示
            String count = date.getCount() + "";
            if (!"0".equals(count) && count != null) {
                canvas.drawCircle((float) (mCellSpace * (i + 1) - radius / 2),
                        (float) ((j + 1) * mCellwide + radius / 2), radius / 2, mCirclePaint);
                canvas.drawText(count, (float) (mCellSpace * (i + 1) - radius / 2 - mCutTextPaint.measureText("3") / 2),
                        (float) ((j + 1) * mCellwide + radius / 2 + mCutTextPaint.measureText("3") / 2), mCutTextPaint);
            }
        }
    }

    /**
     * 單元格狀態: 當前月日期,過去的月的日期,下個月的日期,今天,點擊的日期,提醒日期
     */
    enum State {
        CURRENT_MONTH_DAY, PAST_MONTH_DAY, NEXT_MONTH_DAY, TODAY, CLICK_DAY, REMIND_DAY;
    }

    /**
     * 填充日期的數據
     */
    private void fillDate() {
        fillMonthDate();

    }

    /**
     *  通過getWeekDayFromDate得到一個月第一天是星期幾就可以算出所有的日期的位置 然後依次填充 這裡最好重構一下
     */
    private void fillMonthDate() {
        int monthDay = DateUtil.getCurrentMonthDay();// 今天 
        // 上個月的天數
        int lastMonthDays = DateUtil.getMonthDays(mShowDate.year, mShowDate.month - 1);
        // 當前月的天數 
        int currentMonthDays = DateUtil.getMonthDays(mShowDate.year, mShowDate.month);
        //當月1號是星期幾
        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 postion = i + j * TOTAL_COL;// 單元格位置  
                // 這個月的  
                if (postion >= firstDayWeek && postion < firstDayWeek + currentMonthDays) {
                    day++;
                    if (isCurrentMonth && day == monthDay) {
                        RepayPlanInfo date = RepayPlanInfo.modifiDayForObject(mShowDate, day);
                        mClickCell = new Cell(date, State.TODAY, i, j);
                        date.week = i;
                        rows[j].cells[i] = new Cell(date, State.CLICK_DAY, i, j);
                        continue;
                    }
                    rows[j].cells[i] = new Cell(RepayPlanInfo.modifiDayForObject(mShowDate, day),
                            State.CURRENT_MONTH_DAY, i, j);
                } else if (postion < firstDayWeek) {
                 // 上個月
                    rows[j].cells[i] = new Cell(new RepayPlanInfo(mShowDate.year, mShowDate.month - 1,
                            lastMonthDays - (firstDayWeek - postion - 1)), State.PAST_MONTH_DAY, i, j);
                } else if (postion >= firstDayWeek + currentMonthDays) {
                 // 下個月
                    rows[j].cells[i] = new Cell((new RepayPlanInfo(mShowDate.year, mShowDate.month + 1,
                            postion - firstDayWeek - currentMonthDays + 1)), State.NEXT_MONTH_DAY, i, j);
                }
            }
        }
    }

    /**
     * 繪制提醒單元格
     * 
     * @param i
     * @return
     * 
     */
    public void updateMonthDate(List dateInfos) {
        RepayPlanInfo dateInfo;
        for (int k = 0; k < dateInfos.size(); k++) {
            dateInfo = dateInfos.get(k);
            //當前顯示view為提醒月時繪制提醒日期
            if (mShowDate.year == dateInfo.getYear() && mShowDate.month == dateInfo.getMonth()) {
                int[] cut = getSubscript(dateInfo.getDay());
                rows[cut[0]].cells[cut[1]].state = State.REMIND_DAY;
                rows[cut[0]].cells[cut[1]].date = dateInfo;
                if (mClickCell != null && mClickCell.date.getDay() == dateInfo.getDay()) {
                    mClickCell = rows[cut[0]].cells[cut[1]];
                    measureClickCell(cut[1], cut[0]);
                }
            }
        }
        invalidate();
    }

    /**
     * 根據日期獲得單元格下標
     * @param i
     * @return 
     */
    private int[] getSubscript(int i) {
        int firstDayWeek = DateUtil.getWeekDayFromDate(mShowDate.year, mShowDate.month);
        i = i + firstDayWeek - 1;
        int a = i / 7;
        int b = i % 7;
        int[] cut = { a, b };
        return cut;
    }

    //更新日期,用於月份切換時
    public void update() {
        mClickCell = null;
        mCallBack.changeDate(mShowDate);
        fillDate();
        invalidate();
    }

    //返回當前時間
    public void backToday() {
        initDate();
        invalidate();
    }

    // 點擊選擇切換月份
    public void clickSelect(int year, int month) {
        mShowDate.month = month;
        mShowDate.year = year;
        update();
    }

    // 向右滑動
    public void rightSilde() {
        if (mShowDate.month == 12) {
            mShowDate.month = 1;
            mShowDate.year += 1;
        } else {
            mShowDate.month += 1;
        }
        update();
    }

    // 向左滑動
    public void leftSilde() {
        if (mShowDate.month == 1) {
            mShowDate.month = 12;
            mShowDate.year -= 1;
        } else {
            mShowDate.month -= 1;
        }
        update();
    }
}

2.DateUtil時間工具類

package com.example.calendar;

import android.annotation.SuppressLint;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;

public class DateUtil {

    public static int getMonthDays(int year, int month) {
        if (month > 12) {
            month = 1;
            year += 1;
        } else if (month < 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 && 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) + 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 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) + 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 < 0) {
            week_index = 0;
        }
        return week_index;
    }

    @SuppressLint("SimpleDateFormat")
    public static Date getDateFromString(int year, int month) {
        String dateString = year + "-" + (month > 9 ? month : ("0" + month)) + "-01";
        Date date = null;
        try {
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
            date = sdf.parse(dateString);
        } catch (ParseException e) {
            System.out.println(e.getMessage());
        }
        return date;
    }

    public static boolean isToday(RepayPlanInfo date) {
        return (date.year == DateUtil.getYear() && date.month == DateUtil.getMonth()
                && date.day == DateUtil.getCurrentMonthDay());
    }

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

    public static String getTimeParseInt(int year, int month, int day) {
        String dateString = year + "" + (month > 9 ? month : ("0" + month)) 
                            + (day > 9 ? day : ("0" + day));
        return dateString;
    }

    public static String getTimeParseInt(int year, int month) {
        String dateString = year + "" + (month > 9 ? month : ("0" + month));
        return dateString;
    }
}

3.自定義日期類RepayPlanInfo

package com.example.calendar.data;

import java.io.Serializable;
import package com.example.calendar.DateUtil;
import android.os.Parcel;
import android.os.Parcelable;

/**
 * 自定義的日期類
 * 
 **/
public class RepayPlanInfo implements Serializable {

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

    public RepayPlanInfo(int year, int month, int day) {
        if (month > 12) {
            month = 1;
            year++;
        } else if (month < 1) {
            month = 12;
            year--;
        }
        this.year = year;
        this.month = month;
        this.day = day;
    }

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

    public static RepayPlanInfo modifiDayForObject(RepayPlanInfo date, int day) {
        RepayPlanInfo modifiDate = new RepayPlanInfo(date.year, date.month, day);
        return modifiDate;
    }

    @Override
    public String toString() {
        return year + "-" + month + "-" + 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;
    }

}

好瞭,自定義的view已經準備好瞭,接下來就是使用瞭。

3.使用

首先,左右滑動使用的是viewpage,為瞭使能無限滑動,這裡我們自定義一個PagerAdapter 。傳入一個日歷卡數組,讓ViewPager循環復用這幾個日歷卡,避免消耗內存。
同時viewpage在左右滑動時要判斷是左滑還是右滑去加載日歷數據,所以這裡自定義瞭OnPageChangeListener

package com.example.calendar;

import android.os.Parcelable;
import android.support.v4.view.PagerAdapter;
import android.support.v4.view.ViewPager;
import android.view.View;

public class CustomViewPagerAdapter extends PagerAdapter {
    private V[] views;

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

    @Override
    public void finishUpdate(View arg0) {
    }

    @Override
    public void notifyDataSetChanged() {
        super.notifyDataSetChanged();
    }

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

    @Override
    public Object instantiateItem(View arg0, int arg1) {
        if (((ViewPager) arg0).getChildCount() == views.length) {
            ((ViewPager) arg0).removeView(views[arg1 % views.length]);
        }
        ((ViewPager) arg0).addView(views[arg1 % views.length], 0);

        return views[arg1 % views.length];
    }

    @Override
    public boolean isViewFromObject(View arg0, Object arg1) {
        return arg0 == (arg1);
    }

    @Override
    public Parcelable saveState() {
        return null;
    }

    @Override
    public void destroyItem(View arg0, int arg1, Object arg2) {
        // TODO Auto-generated method stub
    }

    @Override
    public void startUpdate(View arg0) {

    }

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

CalendarActivity.java

package com.example.calendar;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.crfchina.market.cycleloans.data.RepayPlanInfo;
import com.crfchina.market.cycleloans.util.DateUtil;
import com.crfchina.market.cycleloans.view.CalendarView;
import com.crfchina.market.cycleloans.view.CalendarView.CallBack;
import com.crfchina.market.cycleloans.widget.CustomViewPagerAdapter;
import com.crfchina.market.cycleloans.widget.HomePopMenuWindow;

import android.os.Build;
import android.os.Bundle;
import android.os.IBinder;
import android.os.RemoteException;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.support.v4.view.ViewPager;
import android.support.v4.view.ViewPager.OnPageChangeListener;
import android.view.View;
import android.view.WindowManager;
import android.widget.AdapterView;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import android.widget.TextView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.PopupWindow.OnDismissListener;

public class CalendarActivityextends Activity implements CallBack {
    private ViewPager viewPager;
    private CustomViewPagerAdapter viewPagerAdapter;
    private LinearLayout linearRepayPlan;
    private TextView showYearView, showMonthView, title, xhdtxtMenu;

    private List remindDateInfos = new ArrayList();
    private List menuDateInfos = new ArrayList();
    private CalendarView[] calendarViews;
    private int width;
    private int currentYear = DateUtil.getYear();
    private int currentMonth = DateUtil.getMonth();
    private Context context;


    @Override
    protected void onStart() {
        // TODO Auto-generated method stub
        super.onStart();
    }

    @Override
    protected void onStop() {
        // TODO Auto-generated method stub
        super.onStop();
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_calendar);
        context = this;
        initData();
        initView();
    }

    private void initData() {
        for (int i = 0; i < 6; i++) {
            RepayPlanInfo info = new RepayPlanInfo();
            info.setYear(currentYear);
            info.setMonth(currentMonth);
            if (currentMonth == 12) {
                currentYear = currentYear + 1;
                currentMonth = 1;
            } else {
                currentMonth += 1;
            }
            menuDateInfos.add(0, info);
        }

        RepayPlanInfo info = new RepayPlanInfo();
        info.setBillDate("2017-08-15");
        info.setCount(2);
        repayDateInfos.add(info);

    }

    private void initView() {
        viewPager = (ViewPager) findViewById(R.id.viewpager);
        showMonthView = (TextView) findViewById(R.id.show_month_view);
        showYearView = (TextView) findViewById(R.id.show_year_view);
        showYearView.setText(TimeUtil.getCurrentYear1());
        showMonthView.setText(TimeUtil.getCurrentMonth1() + "/");

        createMassCalendarViews(this, 5, this);

        viewPagerAdapter = new CustomViewPagerAdapter(calendarViews);
        viewPager.setAdapter(viewPagerAdapter);
        viewPager.setCurrentItem(498);
        viewPager.setOnPageChangeListener(new CalendarViewPagerLisenter(viewPagerAdapter));
        /**
         * 當有提醒數據時,調用此方法繪制提醒日期
         */
        updateData();
    }

    public void OnButtonClick(View view) {
        switch (view.getId()) {
        case R.id.img_calendar:
            showPopMenu();
            break;
        case R.id.xhdTopBack:
            finish();
            break;
        default:
            break;
        }
    }

    /**
     * 顯示彈窗
     */
    private void showPopMenu() {
        // 點擊彈出一個popupwindow
        final HomePopMenuWindow pop = new HomePopMenuWindow(this, menuDateInfos, 1);
        // 定義彈窗按鈕
        pop.showAsDropDown1(findViewById(R.id.img_calendar));
        pop.setOnItemClickListener(new OnItemClickListener() {

            @Override
            public void onItemClick(AdapterView parent, View view, int position, long id) {
                RepayPlanInfo info = menuDateInfos.get(position);
                CalendarView[] mShowViews = viewPagerAdapter.getAllItems();
                mShowViews[viewPager.getCurrentItem() % mShowViews.length].clickSelect(info.getYear(), info.getMonth());
                pop.dismiss();
            }
        });
        setBackgroundAlpha(0.5f);
        pop.setOnDismissListener(new OnDismissListener() {

            @Override
            public void onDismiss() {
                setBackgroundAlpha(1.0f);

            }
        });
    }

    /**
     * 設置添加屏幕的背景透明度
     * 
     * @param bgAlpha
     *            屏幕透明度0.0-1.0 1表示完全不透明
     */
    public void setBackgroundAlpha(float bgAlpha) {
        WindowManager.LayoutParams lp = getWindow().getAttributes();
        lp.alpha = bgAlpha;
        getWindow().setAttributes(lp);
    }

    //繪制提醒日期
    private void updateData() {
        CalendarView[] mShowViews = viewPagerAdapter.getAllItems();
        mShowViews[viewPager.getCurrentItem() % mShowViews.length].updateMonthDate(repayDateInfos);
    }

    /**
     * 生產多個CalendarView
     * 
     */
    private void createMassCalendarViews(Context context, int count, CallBack callBack) {
        calendarViews = new CalendarView[count];
        for (int i = 0; i < count; i++) {
            calendarViews[i] = new CalendarView(context, callBack);
        }
    }

    class CalendarViewPagerLisenter implements OnPageChangeListener {

        private SildeDirection mDirection = SildeDirection.NO_SILDE;
        int mCurrIndex = 498;
        private CalendarView[] mShowViews;

        public CalendarViewPagerLisenter(CustomViewPagerAdapter viewAdapter) {
            super();
            this.mShowViews = viewAdapter.getAllItems();
        }

        @Override
        public void onPageScrollStateChanged(int arg0) {
            // TODO Auto-generated method stub
        }

        @Override
        public void onPageScrolled(int arg0, float arg1, int arg2) {
            // TODO Auto-generated method stub
        }

        @Override
        public void onPageSelected(int arg0) {
            measureDirection(arg0);
            updateCalendarView(arg0);
            linearRepayPlan.setVisibility(View.GONE);

        }

        private void updateCalendarView(int arg0) {
            if (mDirection == SildeDirection.RIGHT) {
                mShowViews[arg0 % mShowViews.length].rightSilde();
            } else if (mDirection == SildeDirection.LEFT) {
                mShowViews[arg0 % mShowViews.length].leftSilde();
            }
            mDirection = SildeDirection.NO_SILDE;
        }

        /**
         * 判斷滑動方向
         * 
         * @param arg0
         */
        private void measureDirection(int arg0) {
            if (arg0 > mCurrIndex) {
                mDirection = SildeDirection.RIGHT;

            } else if (arg0 < mCurrIndex) {
                mDirection = SildeDirection.LEFT;
            }
            mCurrIndex = arg0;
        }

    }

    enum SildeDirection {
        RIGHT, LEFT, NO_SILDE;
    }

    /**
     * CandlendarView回到當前日期
     */
    private void backTodayCalendarViews() {
        if (calendarViews != null)
            for (int i = 0; i < calendarViews.length; i++) {
                calendarViews[i].backToday();
            }
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
    }

    //viewpage滑動時顯示當前日期
    public void setShowDateViewText(int year, int month) {
        showYearView.setText(year + "");
        if (month < 10) {
            showMonthView.setText("0" + month + "/");
        } else {
            showMonthView.setText(month + "/");
        }
    }

    @Override
    public void onMesureCellHeight(float cellSpace, float cellwide) {

    }

    @Override
    public void clickDate(RepayPlanInfo dates) {
        // 當點擊日歷時回調
    }

    @Override
    public void changeDate(RepayPlanInfo dates) {
        //viewpage滑動時回調
        setShowDateViewText(dates.year, dates.month);
    }

}

上面代碼中我還使用瞭popupWindow,就是彈出一個listview,可以點擊切換月份,我就不貼代碼瞭

佈局activity_calendar



    

        

            

            
        

        
    

    

    
    

好瞭,大功告成瞭,相關代碼就這些瞭~~~

You May Also Like