本文实例为大家分享了android自定义view实现日历打卡签到的具体代码,供大家参考,具体内容如下
1.说明
自己写一个view实现每天签到的功能,设置背景图片
源码下载
2.效果图

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 {
//参考网址:http://www.51sjk.com/Upload/Articles/1/0/245/245923_20210619000122178.jpg
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;
}
}
}
}
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。
________9月的记忆丶