欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

Android自定义view实现日历打卡签到

程序员文章站 2022-04-20 14:22:29
本文实例为大家分享了android自定义view实现日历打卡签到的具体代码,供大家参考,具体内容如下1.说明自己写一个view实现每天签到的功能,设置背景图片源码下载2.效果图3.主界面package...

本文实例为大家分享了android自定义view实现日历打卡签到的具体代码,供大家参考,具体内容如下

1.说明

自己写一个view实现每天签到的功能,设置背景图片

源码下载

2.效果图

Android自定义view实现日历打卡签到

3.主界面

package com.example.myapplication30;
 
import androidx.appcompat.app.appcompatactivity;
 
import android.annotation.suppresslint;
import android.os.bundle;
import android.util.log;
import android.view.view;
import android.widget.button;
import android.widget.textview;
import java.util.arraylist;
import java.util.calendar;
import java.util.list;
 
public class mainactivity extends appcompatactivity {
    //参考网址:https://blog.csdn.net/macaopark/article/details/102069775
    private textview mtvdaysum;
    private textview mtvmonth;
    private signview mcvcalendar;
    private list<signentity> data;
    private calendar calendar;
 
    @override
    protected void oncreate(bundle savedinstancestate) {
        super.oncreate(savedinstancestate);
        setcontentview(r.layout.activity_main);
        mtvdaysum = findviewbyid(r.id.punch_tv_day_sum);
        mtvmonth = findviewbyid(r.id.punch_tv_month);
        mcvcalendar = findviewbyid(r.id.punch_cv_calendar);
    }
 
    @override
    protected void onstart() {
        super.onstart();
        onready();
    }
 
    @suppresslint("settexti18n")
    private void onready() {
          calendar = calendar.getinstance();
        int year = calendar.get(calendar.year);
        int month = calendar.get(calendar.month);
        //int date =  calendar.get(calendar.date);
        int dayofmonthtoday = calendar.get(calendar.day_of_month);
        list<signdate> signdates = new arraylist<>();
        signdates.add(new signdate(2021, 5, 1, true));
        signdates.add(new signdate(2021, 5, 2, true));
        signdates.add(new signdate(2021, 5, 3, true));
        signdates.add(new signdate(2021, 5, 4, true));
        signdates.add(new signdate(2021, 5, 5, true));
 
        mtvdaysum.settext("本期连续登录\t"+signdates.size()+"\t天");
        mtvmonth.settext(year+"年"+getresources().getstringarray(r.array.month_array)[month]+"\t"+dayofmonthtoday+"日");
 
        data = new arraylist<>();
        for (int i = 1; i <= dayofmonthtoday; i++) {
            signentity signentity = new signentity();
            if (i == dayofmonthtoday) {
                signentity.setdaytype(2);
            } else {
                signentity.setdaytype(1);
            }
            for (int j = 0; j < signdates.size(); j++) {
                if (signdates.get(j).getday() == i) {
                    signentity.setdaytype(0);
                    break;
                } else if (dayofmonthtoday == i) {
                    signentity.setdaytype(2);
                } else {
                    signentity.setdaytype(1);
                }
            }
            data.add(signentity);
        }
 
        signadapter signadapter = new signadapter(data);
        mcvcalendar.setadapter(signadapter);
    }
 
}

4.适配器

package com.example.myapplication30;
 
 
import java.util.list;
 
/**
 * signadapter
 * created by e.m on 2016/4/21.
 */
public class signadapter extends calendaradapter {
    private list<signentity> data;
 
    public signadapter(list<signentity> data) {
        this.data = data;
    }
 
    @override
    public signview.daytype gettype(int dayofmonth) {
        return signview.daytype.valueof(data.get(dayofmonth - 1).getdaytype());
    }
}

5.自定义view

package com.example.myapplication30;
 
 
import android.content.context;
import android.graphics.bitmap;
import android.graphics.bitmapfactory;
import android.graphics.bitmapshader;
import android.graphics.canvas;
import android.graphics.color;
import android.graphics.composeshader;
import android.graphics.lineargradient;
import android.graphics.paint;
import android.graphics.path;
import android.graphics.porterduff;
import android.graphics.radialgradient;
import android.graphics.rect;
import android.graphics.shader;
import android.graphics.sweepgradient;
import android.util.attributeset;
import android.view.motionevent;
import android.view.view;
 
 
import java.util.calendar;
 
/**
 * 签到日历控件
 * created by e.m on 2016/4/20.
 */
public class signview extends view {
    private static final string[] week_mark = {"一", "二", "三", "四", "五", "六", "日"};
 
    private static final int max_column = 7;
    /**
     * 周内
     */
    private static final int color_marker_weekday = 0xff999999;
    private static final int color_marker_weekend = 0xff1b89cd;
    /**
     * 已签到背景色
     */
    //private static final int color_background_highlight = 0xffff0000;
    /**
     * 未签到背景色
     */
    private static final int color_background_normal = 0xff9c9c9c;
    /**
     * 等待签到背景色
     */
    private static final int color_background_wait = 0xfffe7471;
    /**
     * 已签到文字颜色
     */
    private static final int color_text_highlight = 0xffffffff;
    /**
     * 未签到文字颜色
     */
    private static final int color_text_normal = 0xff606060;
//    /**
//     * 不可用文字颜色
//     */
//    private static final int color_text_disabled = 0xffd4d4d4;
 
    private static final int marker_text_size = 40;
    private static final int cell_text_size = 40;
 
    private static final int vertical_space = 51;
    private static final int vertical_margin = 62;
    private static final int horizontal_margin = 39;
    private static final int cell_size = 80;
    private static final int wait_line_size = 14;
 
    private int dayofmonthtoday;
    private int markertexty;
    private int verticalcelltop;
    private int sumdayofmonth;
    private int daysoffirstweek;
    private int horizontalspace;
    private int deltatextcelly;
    private int deltatextmarkery;
 
    private int verticalspace;
    private int verticalmargin;
    private int horizontalmargin;
    private int cellsize;
    private int waitlinesize;
 
    private path waitpath;
    private rect waitrect;
    private paint paintweekday;
    private paint paintweekend;
    private paint painttextnormal;
    private paint painttexthighlight;
    private paint paintbackgroundwait;
    private paint paintbackgroundnormal;
    private paint paintbackgroundhighlight;
    private calendaradapter adapter;
 
    public signview(context context) {
        this(context, null);
    }
 
    public signview(context context, attributeset attrs) {
        this(context, attrs, -1);
    }
 
    public signview(context context, attributeset attrs, int defstyleattr) {
        super(context, attrs, defstyleattr);
        initresolution();
        initpaint();
        initdata();
    }
 
    private void initresolution() {
//        resolutionutil = resolutionutil.getinstance();
//        verticalspace = resolutionutil.formatvertical(vertical_space);
//        verticalmargin = resolutionutil.formatvertical(vertical_margin);
//        horizontalmargin = resolutionutil.formathorizontal(horizontal_margin);
//        cellsize = resolutionutil.formatvertical(cell_size);
//        waitlinesize = resolutionutil.formatvertical(wait_line_size);
        verticalspace = vertical_space;
        verticalmargin = vertical_margin;
        horizontalmargin = horizontal_margin;
        cellsize = cell_size;
        waitlinesize = wait_line_size;
 
    }
 
    private void initpaint() {
//        int markertextsize = resolutionutil.formatvertical(marker_text_size);
//        int celltextsize = resolutionutil.formatvertical(cell_text_size);
        int markertextsize = marker_text_size;
        int celltextsize = cell_text_size;
 
        paintweekday = new paint();
        paintweekday.setantialias(true);
        paintweekday.setcolor(color_marker_weekday);
        paintweekday.settextsize(markertextsize);
        paintweekday.settextalign(paint.align.center);
 
        paintweekend = new paint();
        paintweekend.setantialias(true);
        paintweekend.setcolor(color_marker_weekend);
        paintweekend.settextsize(markertextsize);
        paintweekend.settextalign(paint.align.center);
 
        painttextnormal = new paint();
        painttextnormal.setantialias(true);
        painttextnormal.setcolor(color_text_normal);
        painttextnormal.settextsize(celltextsize);
        painttextnormal.settextalign(paint.align.center);
 
        painttexthighlight = new paint();
        painttexthighlight.setantialias(true);
        painttexthighlight.setcolor(color_text_highlight);
        painttexthighlight.settextsize(celltextsize);
        painttexthighlight.settextalign(paint.align.center);
 
        paintbackgroundwait = new paint();
        paintbackgroundwait.setantialias(true);
        paintbackgroundwait.setcolor(color_background_wait);
        paintbackgroundwait.setstrokewidth(2);
        paintbackgroundwait.setstyle(paint.style.stroke);
 
        paintbackgroundnormal = new paint();
        paintbackgroundnormal.setantialias(true);
        paintbackgroundnormal.setcolor(color_background_normal);
        paintbackgroundnormal.setstrokewidth(2);
        paintbackgroundnormal.setstyle(paint.style.stroke);
 
        paintbackgroundhighlight = new paint();
        paintbackgroundhighlight.setantialias(true);
        paintbackgroundhighlight.setstrokewidth(2);
        paintbackgroundhighlight.setstyle(paint.style.fill);
        //颜色
        //paintbackgroundhighlight.setcolor(color_background_highlight);
        //多种颜色数组
        //int[] colors = {color.red,color.green,color.blue,color.yellow,color.magenta};
        //float[] position = {0f, 0.2f, 0.4f, 0.6f, 1.0f};
        //shader shader1 = new lineargradient(100,850,600,850,colors,position,shader.tilemode.clamp);
        //paintbackgroundhighlight.setshader(shader1);
        //设置背景图片
       /* bitmap placeholder = bitmapfactory.decoderesource(getresources(), r.mipmap.small);
        shader shader1 = new bitmapshader(placeholder, shader.tilemode.clamp, shader.tilemode.clamp);
        paintbackgroundhighlight.setshader(shader1);*/
 
 
    }
 
    private void initdata() {
        paint.fontmetricsint fmimarker = paintweekday.getfontmetricsint();
        deltatextmarkery = -(fmimarker.bottom - fmimarker.top) / 2 - fmimarker.top;
        markertexty = verticalmargin + cellsize / 2;
 
        paint.fontmetricsint fmicell = painttextnormal.getfontmetricsint();
        deltatextcelly = -(fmicell.bottom - fmicell.top) / 2 - fmicell.top;
        verticalcelltop = verticalmargin + cellsize;
 
        calendar calendartoday = calendar.getinstance();
        dayofmonthtoday = calendartoday.get(calendar.day_of_month);
        int dayofweek;
        sumdayofmonth = calendartoday.getactualmaximum(calendar.day_of_month);
 
        calendar calendarfirstday = calendar.getinstance();
        calendarfirstday.set(calendar.day_of_month, 1);
        dayofweek = calendarfirstday.get(calendar.day_of_week);
        if (dayofweek == calendar.sunday) {
            dayofweek = 7;
        } else {
            dayofweek = dayofweek - 1;
        }
        daysoffirstweek = max_column - dayofweek + 1;
    }
 
    private void createwaitbackground(int topx, int topy) {
        waitpath = new path();
        waitpath.moveto(topx, topy + waitlinesize);
        waitpath.lineto(topx, topy);
        waitpath.lineto(topx + waitlinesize, topy);
 
        waitpath.moveto(topx + cellsize - waitlinesize, topy + cellsize);
        waitpath.lineto(topx + cellsize, topy + cellsize);
        waitpath.lineto(topx + cellsize, topy + cellsize - waitlinesize);
 
        waitrect = new rect(topx, topy, topx + cellsize, topy + cellsize);
    }
 
    @override
    protected void onsizechanged(int w, int h, int oldw, int oldh) {
        super.onsizechanged(w, h, oldw, oldh);
        horizontalspace = (w - max_column * cellsize - horizontalmargin * 2) / (max_column - 1);
    }
 
    @override
    public void draw(canvas canvas) {
        super.draw(canvas);
        drawweekmark(canvas);
        drawcellsbackground(canvas);
        drawcells(canvas);
    }
 
    private void drawweekmark(canvas canvas) {
        int y = markertexty + deltatextmarkery;
        for (int i = 0; i < 7; i++) {
            int x = horizontalmargin + i * (horizontalspace + cellsize)
                    + cellsize / 2;
            if (i < 5) {
                canvas.drawtext(week_mark[i], x, y, paintweekday);
            } else {
                canvas.drawtext(week_mark[i], x, y, paintweekend);
            }
        }
    }
 
    private void drawcellsbackground(canvas canvas) {
        for (int i = 1; i <= dayofmonthtoday; i++) {
            drawcellbackground(canvas, i, getcolumnindex(i), getrowindex(i));
        }
    }
 
    /**
     * 根据行列序号绘制日期背景
     *
     * @param canvas     画布
     * @param dayofmonth 日期
     * @param column     列序号
     * @param row        行序号
     */
    private void drawcellbackground(canvas canvas, int dayofmonth, int column, int row) {
        int x = horizontalmargin + column * (horizontalspace + cellsize)
                + cellsize / 2;
        int y = verticalcelltop + verticalspace * (row + 1) + cellsize * row + cellsize / 2;
        if (adapter != null) {
            daytype daytype = adapter.gettype(dayofmonth);
            switch (daytype) {
                case waiting:
                    if (waitpath == null) {
                        createwaitbackground(x - cellsize / 2, y - cellsize / 2);
                    }
                    canvas.drawpath(waitpath, paintbackgroundwait);
                    break;
                case signed:
                 //     canvas.drawcircle(x, y, cellsize/2, paintbackgroundhighlight);
                //  canvas.drawrect(x - 60, y - 60, x + 60, y + 60, paintbackgroundhighlight);// 正方形
                   // bitmap placeholder = bitmapfactory.decoderesource(getresources(), r.mipmap.purtest);
                 //   canvas.drawbitmap(placeholder,);wcircle(x, y, cellsize/2, paintbackgroundhighlight);
                    canvas.drawbitmap(bitmapfactory.decoderesource(getresources(), r.mipmap.small3),x-40, y-40 , paintbackgroundhighlight);
                    break;
                default:
                    canvas.drawcircle(x, y, cellsize / 2, paintbackgroundnormal);
                    break;
            }
        } else {
            canvas.drawcircle(x, y, cellsize / 2, paintbackgroundnormal);
        }
    }
 
    private void drawcells(canvas canvas) {
        for (int i = 1; i <= sumdayofmonth; i++) {
            drawcell(canvas, i, getcolumnindex(i), getrowindex(i));
        }
    }
 
    /**
     * 根据行列序号绘制日期
     *
     * @param canvas     画布
     * @param dayofmonth 日期
     * @param column     列序号
     * @param row        行序号
     */
    private void drawcell(canvas canvas, int dayofmonth, int column, int row) {
        int x = horizontalmargin + column * (horizontalspace + cellsize)
                + cellsize / 2;
        int y = verticalcelltop + verticalspace * (row + 1) + cellsize * row + cellsize / 2
                + deltatextcelly;
        if (adapter != null && dayofmonth <= dayofmonthtoday) {
            daytype daytype = adapter.gettype(dayofmonth);
            paint paint;
            switch (daytype) {
                case signed:
                    paint = painttexthighlight;
                    break;
                default:
                    paint = painttextnormal;
                    break;
            }
            canvas.drawtext(string.valueof(dayofmonth), x, y, paint);
        } else {
            canvas.drawtext(string.valueof(dayofmonth), x, y, painttextnormal);
        }
    }
 
    /**
     * 获取列序号
     *
     * @param dayofmonth 日期
     * @return 列序号
     */
    private int getcolumnindex(int dayofmonth) {
        calendar calendar = calendar.getinstance();
        calendar.set(calendar.day_of_month, dayofmonth);
        int dayofweek = calendar.get(calendar.day_of_week);
        if (dayofweek == calendar.sunday) {
            dayofweek = 6;
        } else {
            dayofweek = dayofweek - 2;
        }
        return dayofweek;
    }
 
    /**
     * 获取行序号
     *
     * @param dayofmonth 日期
     * @return 行序号
     */
    private int getrowindex(int dayofmonth) {
        float weight = (dayofmonth - daysoffirstweek) / (max_column * 1f);
        double rowindexdouble = math.abs(math.ceil(weight));
        return (int) rowindexdouble;
    }
 
    @override
    public boolean ontouchevent(motionevent event) {
        if (event.getaction() == motionevent.action_up) {
            float x = event.getx();
            float y = event.gety();
            if (waitpath != null) {
                if (adapter.gettype(dayofmonthtoday).equals(daytype.waiting)) {
                    if (x >= waitrect.left && y >= waitrect.top && x <= waitrect.right && y <= waitrect.bottom) {
                        if (ontodayclicklistener != null) {
                            ontodayclicklistener.ontodayclick();
                        }
                    }
                }
            }
        }
        return true;
    }
 
    public void setadapter(calendaradapter adapter) {
        this.adapter = adapter;
        this.invalidate();
    }
 
    public int getdayofmonthtoday() {
        return dayofmonthtoday;
    }
 
    public void notifydatasetchanged() {
        invalidate();
    }
 
    private ontodayclicklistener ontodayclicklistener;
 
    public void setontodayclicklistener(ontodayclicklistener ontodayclicklistener) {
        this.ontodayclicklistener = ontodayclicklistener;
    }
 
    public interface ontodayclicklistener {
        void ontodayclick();
    }
 
    public enum daytype {
        /**
         * 已签到状态,时间已过
         */
        signed(0),
        /**
         * 未签到状态,时间已过
         */
        unsigned(1),
        /**
         * 等待状态,即当日还未签到
         */
        waiting(2),
        /**
         * 不可达到状态,未到时间
         */
        unreachable(3),
        /**
         * 不可用状态,非当前月份
         */
        disabled(4);
 
        private int value;
 
        daytype(int value) {
            this.value = value;
        }
 
        public int getvalue() {
            return value;
        }
 
        public static daytype valueof(int value) {
            switch (value) {
                case 0:
                    return signed;
                case 1:
                    return unsigned;
                case 2:
                    return waiting;
                case 3:
                    return unreachable;
                case 4:
                    return disabled;
                default:
                    return disabled;
            }
        }
    }
}

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。