android自定义日历实现事件提醒

转载请注明出处:http://blog.csdn.net/ym4189/article/details/77008361

1.概述

前段时间项目需要一个日历提醒,需求是:可以左右无限滑动,可点击监听,根据事件日期在视图中描出,右上角显示事件个数。
在网上搜了很多,但是不是很满足项目特定的需求,所以在网上的例子的基础上自定义了一个,供大家参考。

2.先上图

这里写图片描述

这里日期是自己画的,没有使用GridView,使用自定义view更方便。
我们通过计算每个月的日期,然后根据计算出来的位置绘制我们的日期。这里使用标准的6*7方格图。
我会把注释放在代码里,直接上代码:

1.CalendarView

package com.example.calendar;

import java.util.List;

import com.example.calendar.DateInfo;
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 DateInfo 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(DateInfo 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 DateInfo();
        //填充日期的数据
        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;
            DateInfo 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 DateInfo date;
        public State state;
        /**
         * i = 行 j = 列
         */
        public int i;
        public int j;

        public Cell(DateInfo 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) {
                        DateInfo date = DateInfo.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(DateInfo.modifiDayForObject(mShowDate, day),
                            State.CURRENT_MONTH_DAY, i, j);
                } else if (postion < firstDayWeek) {
                 // 上个月
                    rows[j].cells[i] = new Cell(new DateInfo(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 DateInfo(mShowDate.year, mShowDate.month + 1,
                            postion - firstDayWeek - currentMonthDays + 1)), State.NEXT_MONTH_DAY, i, j);
                }
            }
        }
    }

    /**
     * 绘制提醒单元格
     * 
     * @param i
     * @return
     * 
     */
    public void updateMonthDate(List<DateInfo> dateInfos) {
        DateInfo 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.自定义日期类DateInfo

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 DateInfo implements Serializable {

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

    public DateInfo(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 DateInfo() {
        this.year = DateUtil.getYear();
        this.month = DateUtil.getMonth();
        this.day = DateUtil.getCurrentMonthDay();
    }

    public static DateInfo modifiDayForObject(RepayPlanInfo date, int day) {
        DateInfo modifiDate = new DateInfo(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<V extends View> 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.example.calendar.DateInfo;
import com.example.calendar.DateUtil;
import com.example.calendar.CalendarView;
import com.example.calendar.CalendarView.CallBack;
import com.example.calendar.CustomViewPagerAdapter;
import com.example.calendar.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<CalendarView> viewPagerAdapter;
    private LinearLayout linearRepayPlan;
    private TextView showYearView, showMonthView, title, xhdtxtMenu;

    private List<DateInfo> remindDateInfos = new ArrayList<DateInfo>();
    private List<DateInfo> menuDateInfos = new ArrayList<DateInfo>();
    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++) {
            DateInfo info = new DateInfo();
            info.setYear(currentYear);
            info.setMonth(currentMonth);
            if (currentMonth == 12) {
                currentYear = currentYear + 1;
                currentMonth = 1;
            } else {
                currentMonth += 1;
            }
            menuDateInfos.add(0, info);
        }

        DateInfo info = new DateInfo();
        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<CalendarView>(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) {
                DateInfo 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(remindDateInfos);
    }

    /**
     * 生产多个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<CalendarView> 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

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >

    <RelativeLayout
        android:layout_width="fill_parent"
        android:layout_height="40dip"
        android:background="@color/white"
        android:paddingLeft="15dip"
        android:paddingRight="15dip" >

        <LinearLayout
            android:id="@+id/layout"
            android:layout_width="wrap_content"
            android:layout_height="fill_parent"
            android:layout_alignParentLeft="true"
            android:layout_marginLeft="15dp"
            android:orientation="horizontal" >

            <TextView
                android:id="@+id/show_month_view"
                android:layout_width="wrap_content"
                android:layout_height="fill_parent"
                android:layout_alignParentLeft="true"
                android:gravity="center"
                android:text="01/"
                android:textColor="#646464"
                android:textSize="15sp" />

            <TextView
                android:id="@+id/show_year_view"
                android:layout_width="wrap_content"
                android:layout_height="fill_parent"
                android:gravity="center"
                android:text="2017"
                android:textColor="#646464"
                android:textSize="15sp" />
        </LinearLayout>

        <ImageView
            android:id="@+id/img_calendar"
            android:layout_width="40dp"
            android:layout_height="40dp"
            android:layout_alignParentRight="true"
            android:layout_centerVertical="true"
            android:onClick="OnButtonClick"
            android:padding="10dp"
            android:src="@drawable/img_schoolyear" />
    </RelativeLayout>

    <View
        android:layout_width="fill_parent"
        android:layout_height="1px"
        android:background="#20000000" />

    <android.support.v4.view.ViewPager
        android:id="@+id/viewpager"
        android:layout_width="match_parent"
        android:layout_height="280dp"
        android:layout_gravity="center"
        android:background="#ffffff"
        android:paddingLeft="15dip"
        android:paddingRight="15dip" >
    </android.support.v4.view.ViewPager>

</LinearLayout>

好了,大功告成了,相关代码就这些了~~~

  • 3
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 11
    评论
评论 11
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值