首页 > 学院 > 开发设计 > 正文

自定义View日历

2019-11-07 23:42:41
字体:
来源:转载
供稿:网友

今天是周六,趁着还有多余的空闲,把这周的干活拿出来晒一晒。首先看项目的截图。

这个就是项目的截图,很明显这是一个日历,由于有特殊的需求,比如每个日期需要添加点击事件,分别为每天设置不同的考勤信息,类似于这种只能用自定义view去实现。

分析:

1.首先观察日历每一行的背景都是岔开的,这种如何实现。

2.每周六跟周日的日期颜色不一样。

3.特殊日期有圆形图形包起来。

4.星期要跟日期对应起来。

5.需要考虑如果一个月只有28天的话,就不需要绘制那么多行。

技术难点:

1.关于坐标的计算,这个是比较麻烦的,因为涉及到点击事件,还涉及到日期与星期的对应。

2.屏幕适配,坐标的计算以及字体的大小需要根据屏幕的适配进行调整。

3.绘制文字圆形背景的时候,如何保证文字在圆圈的中间。

5.日期切换,数据及逻辑处理等等。

我在拿到项目的需求后,首先我也在网上找了下,也有很多成熟的方案,但是我还是想自己写一些,第一给人的感觉这个应该是不难的,但是实际自己动起手来才发现,事实并不如此。当中的坑是你想不到的。但是只有自己真正的写出来才会进步,我感觉能把这个自己写出来,自定义view方面也都不是什么难事了。

解析思路:

1.为了避免背景被文字覆盖,所以需要先要绘制背景。

2.计算每个月有多少天,每个月的第一天是周几。

3.绘制文字,在绘制文字的同时,需要给文字绘制圆形背景,避免圆形背景覆盖文字。

4.添加点击事件,判断点击的坐标点是在哪个点的范围内。

(这些代码大家复制过去直接能用了)

代码:

时间处理的工具类:

import java.text.ParseException;import java.text.SimpleDateFormat;import java.util.ArrayList;import java.util.Calendar;import java.util.List;import java.util.TimeZone;/* *  @项目名:  Zhukeyunfu  *  @包名:    com.eben.zhukeyunfu.Activity.utils *  @文件名:   DateUtils *  @创建者:   Administrator *  @创建时间:  2016/11/4 15:44 *  @描述:    TODO */public class DateUtils {    PRivate static final String TAG = "DateUtils";    private static String mYear; // 当前年    private static String mMonth; //     private static String mDay;    private static String mWay;    /**     * 获取当前日期几月几号     */    public static String getDateString() {        final Calendar c = Calendar.getInstance();        c.setTimeZone(TimeZone.getTimeZone("GMT+8:00"));        mMonth = String.valueOf(c.get(Calendar.MONTH) + 1);// 获取当前月份        mDay = String.valueOf(c.get(Calendar.DAY_OF_MONTH));// 获取当前月份的日期号码        if(Integer.parseInt(mDay) > MaxDayFromDay_OF_MONTH(Integer.parseInt(mYear),(Integer.parseInt(mMonth)))){            mDay = String.valueOf(MaxDayFromDay_OF_MONTH(Integer.parseInt(mYear),(Integer.parseInt(mMonth))));        }        return mMonth + "" + mDay + "";    }    /**     * 获取当前年月日     *     * @return     */    public static String StringData() {        final Calendar c = Calendar.getInstance();        c.setTimeZone(TimeZone.getTimeZone("GMT+8:00"));        mYear = String.valueOf(c.get(Calendar.YEAR));// 获取当前年份        mMonth = String.valueOf(c.get(Calendar.MONTH) + 1);// 获取当前月份        mDay = String.valueOf(c.get(Calendar.DAY_OF_MONTH));// 获取当前月份的日期号码        if(Integer.parseInt(mDay) > MaxDayFromDay_OF_MONTH(Integer.parseInt(mYear),(Integer.parseInt(mMonth)))){            mDay = String.valueOf(MaxDayFromDay_OF_MONTH(Integer.parseInt(mYear),(Integer.parseInt(mMonth))));        }        return mYear + "-" + (mMonth.length()==1?"0"+mMonth:mMonth) + "-" + (mDay.length()==1?"0"+mDay:mDay);    }    /**     * 根据当前日期获得是星期几     *     * @return     */    public static String getWeek(String time) {        String Week = "";        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");        Calendar c = Calendar.getInstance();        try {            c.setTime(format.parse(time));        } catch (ParseException e) {            e.printStackTrace();        }        if (c.get(Calendar.DAY_OF_WEEK) == Calendar.SUNDAY) {            Week += "周天";        }        if (c.get(Calendar.DAY_OF_WEEK) == Calendar.MONDAY) {            Week += "周一";        }        if (c.get(Calendar.DAY_OF_WEEK) == Calendar.TUESDAY) {            Week += "周二";        }        if (c.get(Calendar.DAY_OF_WEEK) == Calendar.WEDNESDAY) {            Week += "周三";        }        if (c.get(Calendar.DAY_OF_WEEK) == Calendar.THURSDAY) {            Week += "周四";        }        if (c.get(Calendar.DAY_OF_WEEK) == Calendar.FRIDAY) {            Week += "周五";        }        if (c.get(Calendar.DAY_OF_WEEK) == Calendar.SATURDAY) {            Week += "周六";        }        return Week;    }    /**     * 获取今天往后一周的日期(几月几号)     */    public static List<String> getSevendate() {        List<String> dates = new ArrayList<String>();        final Calendar c = Calendar.getInstance();        c.setTimeZone(TimeZone.getTimeZone("GMT+8:00"));        for (int i = 0; i < 7; i++) {            mYear = String.valueOf(c.get(Calendar.YEAR));// 获取当前年份            mMonth = String.valueOf(c.get(Calendar.MONTH) + 1);// 获取当前月份            mDay = String.valueOf(c.get(Calendar.DAY_OF_MONTH) + i);// 获取当前日份的日期号码            if(Integer.parseInt(mDay) > MaxDayFromDay_OF_MONTH(Integer.parseInt(mYear),(i+1))){                mDay = String.valueOf(MaxDayFromDay_OF_MONTH(Integer.parseInt(mYear),(i+1)));            }            String date = mMonth + "" + mDay + "";            dates.add(date);        }        return dates;    }    /**     * 获取今天往后一周的集合     */    public static List<String> get7week() {        String week = "";        List<String> weeksList = new ArrayList<String>();        List<String> dateList = get7date();        for (String s : dateList) {            if (s.equals(StringData())) {                week = "今天";            } else {                week = getWeek(s);            }            weeksList.add(week);        }        return weeksList;    }    public static List<String> get7date() {        List<String> dates = new ArrayList<String>();        final Calendar c = Calendar.getInstance();        c.setTimeZone(TimeZone.getTimeZone("GMT+8:00"));        java.text.SimpleDateFormat sim = new java.text.SimpleDateFormat(                "yyyy-MM-dd");        String date = sim.format(c.getTime());        dates.add(date);        for (int i = 0; i < 6; i++) {            c.add(java.util.Calendar.DAY_OF_MONTH, 1);            date = sim.format(c.getTime());            dates.add(date);        }        return dates;    }    /**得到当年当月的最大日期**/    public static int MaxDayFromDay_OF_MONTH(int year,int month){        Calendar time=Calendar.getInstance();        time.clear();        time.set(Calendar.YEAR,year);        time.set(Calendar.MONTH,month-1);//注意,Calendar对象默认一月为0        int day=time.getActualMaximum(Calendar.DAY_OF_MONTH);//本月份的天数        return day;    }    public static List<String> get7dateBefore() {        List<String> dates = new ArrayList<String>();     Long   currenttime=System.currentTimeMillis();        for(int i=0;i<=6;i++){            SimpleDateFormat format =  new SimpleDateFormat("yyyy-MM-dd");            Long time=new  Long(currenttime-24*3600*1000*i);            String d = format.format(time);            dates.add(d);        }        return dates;    }        /*返回最近的12个月的月份集合*/    public static List<String> get12Month(){        List<String> dates = new ArrayList<String>();        final Calendar c = Calendar.getInstance();        c.setTimeZone(TimeZone.getTimeZone("GMT+8:00"));        mMonth = String.valueOf(c.get(Calendar.MONTH) + 1);// 获取当前月份        int month= Integer.parseInt(mMonth);        for (int i=0;i<12;i++){            if(month-i>0){                dates.add(month-i+"");            }            else if (month-i==0){            dates.add(12+"");            }else if (month-i<0){            dates.add(Math.abs(month-i)+"");            }        }        return dates;    }    /**     * 1-6 代表星期一至星期六 0 代表星期日     * 如果返回 -1 表示参数不正确     */    public static int calWeek(int y, int m, int d) {        if (m < 1 || m > 12 || d < 1 || d > 31) return -1;        if (m == 1) {            m = 13;            y--;        } else if (m == 2) {            m = 14;            y--;        }        int c = y / 100;        y = y - c * 100;        int week = y + y / 4 + c / 4 - 2 * c + 26 * (m + 1) / 10 + d - 1;        week %= 7;        week = week < 0 ? week + 7 : week;        return week;    }    /**     * 获取当月的 天数     * */    public static int getCurrentMonthDay() {        Calendar a = Calendar.getInstance();        a.set(Calendar.DATE, 1);        a.roll(Calendar.DATE, -1);        int maxDate = a.get(Calendar.DATE);        return maxDate;    }    /*获取当前是哪一年*/    public static int getYear(){        final Calendar c = Calendar.getInstance();        c.setTimeZone(TimeZone.getTimeZone("GMT+8:00"));        /*mYear = String.valueOf(c.get(Calendar.YEAR));// 获取当前年份        mMonth = String.valueOf(c.get(Calendar.MONTH) + 1);// 获取当前月份        mDay = String.valueOf(c.get(Calendar.DAY_OF_MONTH));// 获取当前月份的日期号码*/        return c.get(Calendar.YEAR);    }    /*获取当前的月份*/    public static int getMonth(){        final Calendar c = Calendar.getInstance();        c.setTimeZone(TimeZone.getTimeZone("GMT+8:00"));        /*mYear = String.valueOf(c.get(Calendar.YEAR));// 获取当前年份        mMonth = String.valueOf(c.get(Calendar.MONTH) + 1);// 获取当前月份        mDay = String.valueOf(c.get(Calendar.DAY_OF_MONTH));// 获取当前月份的日期号码*/        return c.get(Calendar.MONTH) + 1;    }    /**     * 根据年 月 获取对应的月份 天数     * */    public static int getDaysByYearMonth(int year, int month) {        Calendar a = Calendar.getInstance();        a.set(Calendar.YEAR, year);        a.set(Calendar.MONTH, month - 1);        a.set(Calendar.DATE, 1);        a.roll(Calendar.DATE, -1);        int maxDate = a.get(Calendar.DATE);        return maxDate;    }}

自定义View的代码,因为是做项目的,所以没办法把所有的代码都放进来,后面会建一个文件夹打包把所有需要的放一起,给大家下载使用。

package com.eben.zhukeyunfu.Activity.view;import android.content.Context;import android.graphics.Canvas;import android.graphics.Color;import android.graphics.Paint;import android.graphics.RectF;import android.util.AttributeSet;import android.util.DisplayMetrics;import android.util.Log;import android.view.MotionEvent;import android.view.View;import android.widget.Toast;import com.eben.zhukeyunfu.Activity.utils.DateUtils;import com.eben.zhukeyunfu.R;import java.util.List;/* *  @项目名:  Zhukeyunfu  *  @包名:    com.eben.zhukeyunfu.Activity.view *  @文件名:   MyCalendar *  @创建者:   Administrator *  @创建时间:  2017/2/20 9:29 *  @描述:    TODO */public class MyCalendar extends View {    private static final String TAG = "MyCalendar";    private int           mViewWidth;    private int           mViewHeight;    private Paint         mPaint;    private String[]      mWeek;    private Paint         whiteBgpaint;    private Paint         grayBgpaint;    private Paint         mBlackPaint;    private float         textHight;    private Paint         kuanggongBgpaint;    private List<Integer> mKuanggong;    private List<Integer> mQiantui;    private List<Integer> mZaotui;    private List<Integer> mChiDao;    private List<Integer> mWeiQianDao;    private Paint         zaotuipaint;    private Paint         chidaopaint;    private Paint         weiqiandaopaint;    private Paint         weiqiantuipaint;    private int mWeekFirst1;    private int year;    private int month;    private int mMonthdays;    private Paint grayTextpaint;    private int mZiti20;    private int mZiti27;    private int mZiti25;    private float mTextHeight;    private float mTextWidth;    public MyCalendar(Context context) {        super(context);    }    public MyCalendar(Context context, AttributeSet attrs) {        super(context, attrs);        initWeek();        //initdata();        initZiTi();        initBluePaint();        initGrayPaint();        initGrayTextPaint();        initWhiteBackgroundPaint();        initGrayBackgroundPaint();        initKuangGongPaint();        initWeiQianTuiPaint();        initWeiQianDaoPaint();        initChiDaoPaint();        initZaoTuiPaint();    }    private void initZiTi() {        mZiti20 = sp2px(getContext(),13);        mZiti27 =sp2px(getContext(),15);;        mZiti25 =sp2px(getContext(),17);;        Log.d(TAG,mZiti20+"-----"+mZiti27+"----"+mZiti25);    }    /*ps转成sp保证字体大小不变*/    //注意:这里的paint设置字体大小是非常重要的,但是grayBgpaint.setTextSize(20); 这里的20px,所以需要将sp转成ps转成    public  float px2sp(Context context, int pxValue) {        /**/        DisplayMetrics dm       =context.getResources().getDisplayMetrics();        int            w_screen = dm.widthPixels;        int            h_screen = dm.heightPixels;        int dpi=dm.densityDpi;       // Toast.makeText(context,"屏幕尺寸2:宽度 = " + w_screen + "高度 = " + h_screen + "密度 = " + dm.densityDpi,Toast.LENGTH_SHORT).show();        Log.i(TAG, "屏幕尺寸2:宽度 = " + w_screen + "高度 = " + h_screen + "密度 = " + dm.densityDpi);        /*pxValue 传入 25  27  29*/        return 240*pxValue/260;    }    /**     * sp值转换为px值,保证文字大小不变     *            DisplayMetrics类中属性scaledDensity     * @return     */    public  int sp2px(Context context, float spValue) {        final float fontScale = context.getResources().getDisplayMetrics().scaledDensity;        return (int) (spValue * fontScale + 0.5f);    }    private void initWeek() {        mWeek = new String[]{"",                             "",                             "",                             "",                             "",                             "",                             ""};    }    /*测量*/    @Override    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {        //super.onMeasure(widthMeasureSpec, heightMeasureSpec);        /*特别注意,此处必须要自己进行测量,否则系统会默认讲 wrap_cotentmatch_parent视为相同,也就是会填充整个布局*/        setMeasuredDimension(measure(widthMeasureSpec), measure(heightMeasureSpec));        getViewXY();    }    /*自己测量view的宽高*/    private int measure(int measureSpec) {        int result = 0;        //分别获取测量模式 和 测量大小        int specMode = MeasureSpec.getMode(measureSpec);        int specSize = MeasureSpec.getSize(measureSpec);        //如果是精确度模式,呢就按xml中定义的来        if (specMode == MeasureSpec.EXACTLY) {            result = specSize;        }        //如果是最大值模式,就按我们定义的来        else if (specMode == MeasureSpec.AT_MOST) {            result = mViewWidth * 6 / 8;        }        return result;    }    /*获取自定义view的宽度*/    private void getViewXY() {        mViewWidth = getMeasuredWidth();        mViewHeight = getMeasuredHeight();    }    /*根据paint获取绘制文字的宽高*/    public float getFontHeight(Paint paint)    {        Paint.FontMetrics fm = paint.getFontMetrics();        return (float) (Math.ceil(fm.descent - fm.top) + 2);    }    /*画图*/    @Override    protected void onDraw(Canvas canvas) {        /*先画背景*/        drawbackWeekground(canvas);        /*获取每个竖直列的坐标*/        float x1 = mViewWidth / 8;        float y1 = x1 / 2;        Log.d(TAG, "文字的高度" + textHight / 2);        Log.d(TAG, "y1-----" + y1);        Log.d(TAG, "x1-----" + x1);                /*获取屏幕的宽度*/        /*画文字周日~周六*/        for (int i = 0; i < 7; i++) {            canvas.drawText(mWeek[i],                            x1 * (i + 1) ,                            y1,                            mPaint);        }        /*获取当前月份的天数*/        //mMonthdays = DateUtils.getCurrentMonthDay();        /*获取当前月份的第一天是星期几*/       /* int year  = DateUtils.getYear();        int month = DateUtils.getMonth();*/        Log.d(TAG, "当前月份的第一天是ondraw" + mWeekFirst1);        if (mMonthdays == 28 && mWeekFirst1 == 0) {            /*那么只需要画四行,否则需要❀五行数字*/            /*如果一个月只有28天,并且第一天刚好是周末,那么就刚刚好满足4行共28个数字,那么直需要画四行背景*/            drawbackground(canvas,4);            /*这样的话,就依次画数字就行*/        } else {            /*继续画背景,其他情况,一个月份就需要画5行背景*/            drawbackground(canvas,5);        }            /*画五行数字*/            int j = 1;            for (int i = 1; i <= mMonthdays; i++) {            /*准备开始画数字*/            /*如果是10或者20的,就画个圆*/            /*缺勤的天数处理*/            /*获取圆的坐标*/                float cx = x1 * (mWeekFirst1 + 1);                float cy = x1 * j+y1 ;                /*获取文字的宽高*/                Paint.FontMetrics fm         = kuanggongBgpaint.getFontMetrics();                mTextWidth = kuanggongBgpaint.measureText(i + "");                mTextHeight = fm.bottom - fm.top;                if (mKuanggong!=null&&mKuanggong.contains(i)) {                /*画圆*/                    canvas.drawCircle(cx, cy, mTextHeight / 2 + 8, kuanggongBgpaint);                    canvas.drawText(i + "",                                    cx ,                                    cy+mTextHeight /4,                                    whiteBgpaint);                } else if (mChiDao!=null&&mChiDao.contains(i)) {                /*迟到*/                    canvas.drawCircle(cx, cy, mTextHeight /2 + 8, chidaopaint);                    canvas.drawText(i + "",                                    cx ,                                    cy+mTextHeight /4,                                    whiteBgpaint);                } else if (mQiantui!=null&&mQiantui.contains(i)) {                /*未签到*/                    canvas.drawCircle(cx, cy, mTextHeight / 2 + 8, weiqiandaopaint);                    canvas.drawText(i + "",                                    cx ,                                    cy+mTextHeight /4,                                    whiteBgpaint);                } else if (mZaotui!=null&&mZaotui.contains(i)) {                /**/                    canvas.drawCircle(cx, cy, mTextHeight / 2 + 8, zaotuipaint);                    canvas.drawText(i + "",                                    cx ,                                    cy+mTextHeight /4,                                    whiteBgpaint);                } else if (mQiantui!=null&&mQiantui.contains(i)) {                /*未签退*/                    canvas.drawCircle(cx, cy, mTextHeight / 2 + 8, weiqiantuipaint);                    canvas.drawText(i + "",                                    cx ,                                    cy+mTextHeight /4,                                    whiteBgpaint);                } else {                      /*处理周六与周日的文字颜色问题paint   grayTextpaint*/                    if (mWeekFirst1==0||mWeekFirst1==6){                        canvas.drawText(i + "",                                        cx ,                                        cy+mTextHeight /4,                                        grayTextpaint);                    }else {                        canvas.drawText(i + "",                                        cx ,                                        cy+mTextHeight /4,                                        mBlackPaint);                    }                }                mWeekFirst1++;                if (mWeekFirst1 == 7) {                    mWeekFirst1 = 0;                    j++;                }            }    }    /*画背景*/    private void drawbackWeekground(Canvas canvas){        /*背景1*/        RectF oval1 = new RectF(0, 0, mViewWidth, mViewWidth / 8);// 设置个新的长方形        canvas.drawRoundRect(oval1, 0, 0, whiteBgpaint);//第二个参数是x半径,第三个参数是y半径    }    /*画背景*/    private void drawbackground(Canvas canvas,int hangshu) {         /*背景2*/        RectF oval2 = new RectF(0, mViewWidth / 8, mViewWidth, mViewWidth * 2 / 8);// 设置个新的长方形        canvas.drawRoundRect(oval2, 0, 0, grayBgpaint);//第二个参数是x半径,第三个参数是y半径         /*背景3*/        RectF oval3 = new RectF(0, mViewWidth * 2 / 8, mViewWidth, mViewWidth * 3 / 8);// 设置个新的长方形        canvas.drawRoundRect(oval3, 0, 0, whiteBgpaint);//第二个参数是x半径,第三个参数是y半径         /*背景4*/        RectF oval4 = new RectF(0, mViewWidth * 3 / 8, mViewWidth, mViewWidth * 4 / 8);// 设置个新的长方形        canvas.drawRoundRect(oval4, 0, 0, grayBgpaint);//第二个参数是x半径,第三个参数是y半径        /*背景5*/        RectF oval5 = new RectF(0, mViewWidth * 4 / 8, mViewWidth, mViewWidth * 5 / 8);// 设置个新的长方形        canvas.drawRoundRect(oval5, 0, 0, whiteBgpaint);//第二个参数是x半径,第三个参数是y半径        if(hangshu==4){            return;        }else if(hangshu==5){             /*背景6*/            RectF oval6 = new RectF(0, mViewWidth * 5 / 8, mViewWidth, mViewWidth * 6 / 8);// 设置个新的长方形            canvas.drawRoundRect(oval6, 0, 0, grayBgpaint);//第二个参数是x半径,第三个参数是y半径        }    }    /*触摸处理*/    @Override    public boolean onTouchEvent(MotionEvent event) {        float y = event.getY();        float x = event.getX();        float lineheight=mViewWidth / 8;        float row=x/lineheight;        mWeekFirst1=DateUtils.calWeek(year, month, 1);        Log.d(TAG, "当前月份的第一天是ontouch" + mWeekFirst1);        //获取手指的操作--》按下、移动、松开        Log.d(TAG, "点击了坐标 x = "+x+"  y ="+y);        int action = event.getAction();        switch (action) {            case MotionEvent.ACTION_DOWN://按下                Log.i(TAG, "ACTION_DOWN");                if (y/lineheight>0.0f&&y/lineheight<1.0f){                    Log.d(TAG, "onTouchEvent: 第一行");                }                else if (y/lineheight>1.0f&&y/lineheight<2.0f){                    Log.d(TAG, "onTouchEvent: 第二行");                    for (int i=1;i<=7;i++){                        if (x<i*lineheight+lineheight/2&&x>=i*lineheight-lineheight/2){                            Log.d(TAG,"点击了第2行的,第"+(i)+"");                            Log.d(TAG, "onTouchEvent: 实际坐标点"+(i-mWeekFirst1));                            if (i-mWeekFirst1>0){                                Toast.makeText(getContext(),"点击了"+month+""+(i-mWeekFirst1)+"",Toast.LENGTH_SHORT).show();                            }                            break;                        }                    }                }                else if (y/lineheight>2.0f&&y/lineheight<3.0f){                    Log.d(TAG, "onTouchEvent: 第三行");                    for (int i=1;i<=7;i++){                        if (x<i*lineheight+lineheight/2&&x>=i*lineheight-lineheight/2){                            Log.d(TAG,"点击了第3行的,第"+(i)+"");                            Log.d(TAG, "onTouchEvent: 实际坐标点"+(7-mWeekFirst1+i));                            Toast.makeText(getContext(),"点击了"+month+""+(7-mWeekFirst1+i)+"",Toast.LENGTH_SHORT).show();                            break;                        }                    }                }                else if (y/lineheight>3.0f&&y/lineheight<4.0f){                    Log.d(TAG, "onTouchEvent: 第四行");                    for (int i=1;i<=7;i++){                        if (x<i*lineheight+lineheight/2&&x>=i*lineheight-lineheight/2){                            Log.d(TAG,"点击了第4行的,第"+(i)+"");                            Log.d(TAG, "onTouchEvent: 实际坐标点"+(7-mWeekFirst1+i+7));                            Toast.makeText(getContext(),"点击了"+month+""+(7-mWeekFirst1+i+7)+"",Toast.LENGTH_SHORT).show();                            break;                        }                    }                }                else if (y/lineheight>4.0f&&y/lineheight<5.0f){                    Log.d(TAG, "onTouchEvent: 第五行");                    for (int i=1;i<=7;i++){                        if (x<i*lineheight+lineheight/2&&x>=i*lineheight-lineheight/2){                            Log.d(TAG,"点击了第5行的,第"+(i)+"");                            Log.d(TAG, "onTouchEvent: 实际坐标点"+(7-mWeekFirst1+i+7*2));                            Toast.makeText(getContext(),"点击了"+month+""+(7-mWeekFirst1+i+7*2)+"",Toast.LENGTH_SHORT).show();                            break;                        }                    }                }                else if (y/lineheight>5.0f&&y/lineheight<6.0f){                    Log.d(TAG, "onTouchEvent: 第六行");                    for (int i=1;i<=7;i++){                        if (x<i*lineheight+lineheight/2&&x>=i*lineheight-lineheight/2){                            Log.d(TAG,"点击了第6行的,第"+(i)+"");                            Log.d(TAG, "onTouchEvent: 实际坐标点"+(7-mWeekFirst1+i+7*3));                            if (7-mWeekFirst1+i+7*3<=mMonthdays){                                Toast.makeText(getContext(),"点击了"+month+""+(7-mWeekFirst1+i+7*3)+"",Toast.LENGTH_SHORT).show();                            }                            break;                        }                    }                }else{                    Log.d(TAG, "onTouchEvent: 无效区域");                }                break;            case MotionEvent.ACTION_MOVE://移动                break;            case MotionEvent.ACTION_UP://松开                break;        }        return  true;    }    /*初始化画笔paint*/    private void initZaoTuiPaint() {        zaotuipaint = new Paint();        zaotuipaint.setAntiAlias(true);//去锯齿        zaotuipaint.setColor(getResources().getColor(R.color.zaotui));        zaotuipaint.setTextSize(mZiti20);        //  消除字体锯齿        zaotuipaint.setFlags(Paint.ANTI_ALIAS_FLAG);    }    private void initChiDaoPaint() {        chidaopaint = new Paint();        chidaopaint.setAntiAlias(true);//去锯齿        chidaopaint.setColor(getResources().getColor(R.color.chidao));        chidaopaint.setTextSize(mZiti20);        //  消除字体锯齿        chidaopaint.setFlags(Paint.ANTI_ALIAS_FLAG);    }    private void initWeiQianDaoPaint() {        weiqiandaopaint = new Paint();        weiqiandaopaint.setAntiAlias(true);//去锯齿        weiqiandaopaint.setColor(getResources().getColor(R.color.weiqioandao));        weiqiandaopaint.setTextSize(mZiti20);        //  消除字体锯齿        weiqiandaopaint.setFlags(Paint.ANTI_ALIAS_FLAG);    }    private void initWeiQianTuiPaint() {        weiqiantuipaint = new Paint();        weiqiantuipaint.setAntiAlias(true);//去锯齿        weiqiantuipaint.setColor(getResources().getColor(R.color.weiqioantui));        weiqiantuipaint.setTextSize(mZiti20);        //  消除字体锯齿        weiqiantuipaint.setFlags(Paint.ANTI_ALIAS_FLAG);    }    private void initKuangGongPaint() {        kuanggongBgpaint = new Paint();        kuanggongBgpaint.setAntiAlias(true);//去锯齿        kuanggongBgpaint.setColor(getResources().getColor(R.color.kuanggong));        kuanggongBgpaint.setTextSize(mZiti20);        //  消除字体锯齿        kuanggongBgpaint.setFlags(Paint.ANTI_ALIAS_FLAG);    }    private void initBluePaint() {        mPaint = new Paint();        mPaint.setAntiAlias(true);//去锯齿        mPaint.setColor(getResources().getColor(R.color.skyBlue));        mPaint.setTextAlign(Paint.Align.CENTER);        mPaint.setTextSize(mZiti25);        //  消除字体锯齿        mPaint.setFlags(Paint.ANTI_ALIAS_FLAG);        textHight = getFontHeight(mPaint);    }    private void initGrayPaint() {        mBlackPaint = new Paint();        mBlackPaint.setAntiAlias(true);//去锯齿        mBlackPaint.setColor(Color.BLACK);        mBlackPaint.setTextSize(mZiti27);        mBlackPaint.setTextAlign(Paint.Align.CENTER);        //  消除字体锯齿        mBlackPaint.setFlags(Paint.ANTI_ALIAS_FLAG);    }    private void initGrayBackgroundPaint() {        grayBgpaint = new Paint();        grayBgpaint.setAntiAlias(true);//去锯齿        grayBgpaint.setColor(getResources().getColor(R.color.grayBG));        grayBgpaint.setTextSize(mZiti20);        //  消除字体锯齿        grayBgpaint.setFlags(Paint.ANTI_ALIAS_FLAG);    }    private void initWhiteBackgroundPaint() {        whiteBgpaint = new Paint();        whiteBgpaint.setAntiAlias(true);//去锯齿        whiteBgpaint.setColor(Color.WHITE);        whiteBgpaint.setTextSize(mZiti20);        whiteBgpaint.setTextAlign(Paint.Align.CENTER);        //  消除字体锯齿        whiteBgpaint.setFlags(Paint.ANTI_ALIAS_FLAG);    }    private void initGrayTextPaint() {        grayTextpaint = new Paint();        grayTextpaint.setAntiAlias(true);//去锯齿        grayTextpaint.setColor(getResources().getColor(R.color.grayText));        grayTextpaint.setTextSize(mZiti27);        /*设置文字的重点点坐标开始画*/        grayTextpaint.setTextAlign(Paint.Align.CENTER);        //  消除字体锯齿        grayTextpaint.setFlags(Paint.ANTI_ALIAS_FLAG);    }    /*设置是哪一年*/    public void setYear(int year) {        this.year=year;    }    public void setMonth(int month) {        this.month=month;        /*根据年、月获取 该月份的第一天是星期几*/        mWeekFirst1 = DateUtils.calWeek(year, month, 1);    }    public void setTotalDays(int daysByYearMonth) {        this.mMonthdays=daysByYearMonth;    }    public void setdata(List<Integer> kuanggong,                        List<Integer> qiantui,                        List<Integer> zaotui,                        List<Integer> chiDao,                        List<Integer> weiQianDao) {        this.mKuanggong=kuanggong;        this.mQiantui=qiantui;        this.mZaotui=zaotui;        this.mChiDao=chiDao;        this.mWeiQianDao=weiQianDao;        /*设置数据后,重新绘制图形*/        postInvalidate();    }       /* private void initdata() {        mKuanggong = Arrays.asList(10, 20, 12);        mQiantui = Arrays.asList(6);        mZaotui = Arrays.asList(7);        mChiDao = Arrays.asList(9);        mWeiQianDao = Arrays.asList(13);        }*/}

Activity代码:

package com.eben.zhukeyunfu.Activity.textexampleActivity;import android.net.Uri;import android.os.Build;import android.os.Bundle;import android.support.v7.app.AppCompatActivity;import android.view.KeyEvent;import android.view.View;import android.view.ViewGroup;import android.view.animation.Animation;import android.view.animation.AnimationSet;import android.view.animation.AnimationUtils;import android.widget.BaseAdapter;import android.widget.ImageView;import android.widget.LinearLayout;import android.widget.ListView;import android.widget.TextView;import com.eben.zhukeyunfu.Activity.utils.DateUtils;import com.eben.zhukeyunfu.Activity.view.MyCalendar;import com.eben.zhukeyunfu.R;import com.google.android.gms.appindexing.Action;import com.google.android.gms.appindexing.AppIndex;import com.google.android.gms.appindexing.Thing;import com.google.android.gms.common.api.GoogleApiClient;import java.util.Arrays;import java.util.List;import static com.eben.zhukeyunfu.R.anim.slide_left_in;import static com.eben.zhukeyunfu.R.anim.slide_right_out;/* *  @项目名:  Zhukeyunfu  *  @包名:    com.eben.zhukeyunfu.Activity.textexampleActivity *  @文件名:   HeartActivity *  @创建者:   Administrator *  @创建时间:  2017/2/13 15:28 *  @描述:    TODO */public class KaoQinActivity        extends AppCompatActivity{    private static final String TAG = "FootActivity";    private int           mYear;    private int           mMonth;    private List<Integer> mKuanggong;    private List<Integer> mQiantui;    private List<Integer> mZaotui;    private List<Integer> mChiDao;    private List<Integer> mWeiQianDao;    private TextView     mSwitchMdoe;    private AnimationSet  mAnimationSet1;    private AnimationSet  mAnimationSet2;    private AnimationSet  mAnimationSet3;    private AnimationSet  mAnimationSet4;    private boolean islist = true;    /**     * ATTENTION: This was auto-generated to implement the App Indexing API.     * See https://g.co/AppIndexing/AndroidStudio for more information.     */    private GoogleApiClient mClient;    private LinearLayout mCalendar_mode;    private ListView mList_mode;    private int mDays1Month;    private Myadapter mMyadapter;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        changeColor();        setContentView(R.layout.kaoqin);        //初始化actionbar        //initactionbar();        //初始化布局        //改变手机状态栏颜色        initview();        initanimator();        initlistener();        // ATTENTION: This was auto-generated to implement the App Indexing API.        // See https://g.co/AppIndexing/AndroidStudio for more information.        mClient = new GoogleApiClient.Builder(this).addApi(AppIndex.API)                                                   .build();    }    private void initanimator() {        mAnimationSet1 = (AnimationSet) AnimationUtils.loadAnimation(KaoQinActivity.this, R.anim.slide_left_in);        mAnimationSet2 = (AnimationSet) AnimationUtils.loadAnimation(KaoQinActivity.this, R.anim.slide_left_out);        mAnimationSet3 = (AnimationSet) AnimationUtils.loadAnimation(KaoQinActivity.this, R.anim.slide_right_in);        mAnimationSet4 = (AnimationSet) AnimationUtils.loadAnimation(KaoQinActivity.this, R.anim.slide_right_out);        /*四个动画的监听*/        mAnimationSet1.setAnimationListener(new Animation.AnimationListener() {            @Override            public void onAnimationStart(Animation animation) {            }            @Override            public void onAnimationEnd(Animation animation) {            }            @Override            public void onAnimationRepeat(Animation animation) {            }        });        mAnimationSet2.setAnimationListener(new Animation.AnimationListener() {            @Override            public void onAnimationStart(Animation animation) {            }            @Override            public void onAnimationEnd(Animation animation) {                mCalendar_mode.setVisibility(View.GONE);            }            @Override            public void onAnimationRepeat(Animation animation) {            }        });        mAnimationSet3.setAnimationListener(new Animation.AnimationListener() {            @Override            public void onAnimationStart(Animation animation) {            }            @Override            public void onAnimationEnd(Animation animation) {            }            @Override            public void onAnimationRepeat(Animation animation) {            }        });        mAnimationSet4.setAnimationListener(new Animation.AnimationListener() {            @Override            public void onAnimationStart(Animation animation) {            }            @Override            public void onAnimationEnd(Animation animation) {                mList_mode.setVisibility(View.GONE);            }            @Override            public void onAnimationRepeat(Animation animation) {            }        });    }    private void initlistener() {         /*切换视图*/        mSwitchMdoe.setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View v) {                /*开始切换模式,执行动画*/                if (islist == true) {                    mSwitchMdoe.setText("考勤");                    mCalendar_mode.startAnimation(mAnimationSet2);                    mList_mode.startAnimation(mAnimationSet3);                    mList_mode.setVisibility(View.VISIBLE);                    islist=false;                }else {                    mSwitchMdoe.setText("工资");                    mCalendar_mode.startAnimation(mAnimationSet1);                    mList_mode.startAnimation(mAnimationSet4);                    mCalendar_mode.setVisibility(View.VISIBLE);                    islist=true;                }            }        });        mMyadapter = new Myadapter();        mList_mode.setAdapter(mMyadapter);    }    private void initview() {        ImageView mBack = (ImageView) findViewById(R.id.back_heart);        mBack.setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View v) {                finish();                overridePendingTransition(slide_left_in, slide_right_out);            }        });        /*设置日期*/        final TextView date = (TextView) findViewById(R.id.date);        /*获取当前的月份及年份*/        mYear = DateUtils.getYear();        mMonth = DateUtils.getMonth();        date.setText(mYear + "" + mMonth + "");        /**/        final MyCalendar myCalendar = (MyCalendar) findViewById(R.id.myCalendar);        /*设置日期*/        myCalendar.setYear(mYear);        myCalendar.setMonth(mMonth);        mKuanggong = Arrays.asList(10, 20, 12);        mQiantui = Arrays.asList(6);        mZaotui = Arrays.asList(7);        mChiDao = Arrays.asList(9);        mWeiQianDao = Arrays.asList(13);        /*根据年和月获取天数*/        mDays1Month = DateUtils.getDaysByYearMonth(mYear, mMonth);        myCalendar.setTotalDays(mDays1Month);        myCalendar.setdata(mKuanggong, mQiantui, mZaotui, mChiDao, mWeiQianDao);        /*查看下一月的数据*/        ImageView addMonth = (ImageView) findViewById(R.id.addMonth);        addMonth.setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View v) {                mMonth++;                if (mMonth == 13) {                    mMonth = 1;                    mYear++;                }                date.setText(mYear + "" + mMonth + "");                myCalendar.setYear(mYear);                myCalendar.setMonth(mMonth);                /*根据年和月获取天数*/                myCalendar.setTotalDays(DateUtils.getDaysByYearMonth(mYear, mMonth));                myCalendar.setdata(null, null, null, null, null);                mMyadapter.notifyDataSetChanged();            }        });        /*查看前一月的数据*/        ImageView decreaseMonth = (ImageView) findViewById(R.id.decreaseMonth);        decreaseMonth.setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View v) {                mMonth--;                if (mMonth == 0) {                    mMonth = 12;                    mYear--;                }                date.setText(mYear + "" + mMonth + "");                myCalendar.setYear(mYear);                myCalendar.setMonth(mMonth);                /*根据年和月获取天数*/                myCalendar.setTotalDays(DateUtils.getDaysByYearMonth(mYear, mMonth));                if (mMonth % 4 == 0) {                    myCalendar.setdata(mKuanggong, mQiantui, mZaotui, mChiDao, mWeiQianDao);                } else {                    myCalendar.setdata(null, null, null, null, null);                }                mMyadapter.notifyDataSetChanged();            }        });        /*切换视图*/        mSwitchMdoe = (TextView) findViewById(R.id.switch_mdoe);        /*日历模式view*/        mCalendar_mode = (LinearLayout) findViewById(R.id.calendar_mode);        /*列表模式*/        mList_mode = (ListView) findViewById(R.id.list_mode);    }    private void changeColor() {        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {            //            View decorView = getWindow().getDecorView();            //            int  visibility = View.SYSTEM_UI_FLAG_FULLSCREEN;// 全屏设置            //            int visibility = View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_LAYOUT_STABLE;// 表示允许应用的主题内容占用状态栏的空间            //            decorView.setSystemUiVisibility(visibility);            getWindow().setStatusBarColor(getResources().getColor(R.color.black));// 通知栏颜色        }    }    //处理后退键的情况    @Override    public boolean onKeyDown(int keyCode, KeyEvent event) {        if (keyCode == KeyEvent.KEYCODE_BACK) {            this.finish();  //finish当前activity            overridePendingTransition(slide_left_in, slide_right_out);            return true;        }        return super.onKeyDown(keyCode, event);    }    /**     * ATTENTION: This was auto-generated to implement the App Indexing API.     * See https://g.co/AppIndexing/AndroidStudio for more information.     */    public Action getIndexApiAction() {        Thing object = new Thing.Builder().setName("KaoQin Page") // TODO: Define a title for the content shown.                                          // TODO: Make sure this auto-generated URL is correct.                                          .setUrl(Uri.parse("http://[ENTER-YOUR-URL-HERE]"))                                          .build();        return new Action.Builder(Action.TYPE_VIEW).setObject(object)                                                   .setActionStatus(Action.STATUS_TYPE_COMPLETED)                                                   .build();    }    @Override    public void onStart() {        super.onStart();        // ATTENTION: This was auto-generated to implement the App Indexing API.        // See https://g.co/AppIndexing/AndroidStudio for more information.        mClient.connect();        AppIndex.AppIndexApi.start(mClient, getIndexApiAction());    }    @Override    public void onStop() {        super.onStop();        // ATTENTION: This was auto-generated to implement the App Indexing API.        // See https://g.co/AppIndexing/AndroidStudio for more information.        AppIndex.AppIndexApi.end(mClient, getIndexApiAction());        mClient.disconnect();    }    class  Myadapter extends BaseAdapter{        @Override        public int getCount() {            mDays1Month = DateUtils.getDaysByYearMonth(mYear, mMonth);            if (mDays1Month>0){                return mDays1Month;            }            return 0;        }        @Override        public Object getItem(int position) {            return null;        }        @Override        public long getItemId(int position) {            return 0;        }        @Override        public View getView(int position, View convertView, ViewGroup parent) {            ViewHolder holder=null;            if (holder==null){                holder=new ViewHolder();                convertView=View.inflate(KaoQinActivity.this,R.layout.listitem_kaoqin,null);                holder.mTextView= (TextView) convertView.findViewById(R.id.datalist);            }            holder.mTextView.setText(mMonth+""+(position+1)+"");            return convertView;        }        class  ViewHolder{                TextView mTextView;        }    }}

当然代码有点多了,还有一些自定义的drawable什么的,都放在后面的压缩包里面,最后谢谢大家,供大家参考,这只是我自己的方案,没有参考别人的,获取网上有其他比我容易的方案,也请大家不要拍砖,我这个不是单独的demo,要使用这个需要自己把相关内容加进去才能使用。代码不简洁,也没有优化,请体谅。


发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表