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

这篇文章主要介绍Android如何自定义view实现日历打卡签到,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!

Android是什么

Android是一种基于Linux内核的自由及开放源代码的操作系统,主要使用于移动设备,如智能手机和平板电脑,由美国Google公司和开放手机联盟领导及开发。

1.说明

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

源码下载

2.效果图

3.主界面

packagecom.example.myapplication30;

importandroidx.appcompat.app.AppCompatActivity;

importandroid.annotation.SuppressLint;
importandroid.os.Bundle;
importandroid.util.Log;
importandroid.view.View;
importandroid.widget.Button;
importandroid.widget.TextView;
importjava.util.ArrayList;
importjava.util.Calendar;
importjava.util.List;

publicclassMainActivityextendsAppCompatActivity{
//参考网址:https://blog.csdn.net/MacaoPark/article/details/102069775
privateTextViewmTvDaySum;
privateTextViewmTvMonth;
privateSignViewmCvCalendar;
privateListdata;
privateCalendarcalendar;

@Override
protectedvoidonCreate(BundlesavedInstanceState){
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
protectedvoidonStart(){
super.onStart();
onReady();
}

@SuppressLint("SetTextI18n")
privatevoidonReady(){
calendar=Calendar.getInstance();
intyear=calendar.get(Calendar.YEAR);
intmonth=calendar.get(Calendar.MONTH);
//intdate=calendar.get(Calendar.DATE);
intdayOfMonthToday=calendar.get(Calendar.DAY_OF_MONTH);
ListsignDates=newArrayList<>();
signDates.add(newSignDate(2021,5,1,true));
signDates.add(newSignDate(2021,5,2,true));
signDates.add(newSignDate(2021,5,3,true));
signDates.add(newSignDate(2021,5,4,true));
signDates.add(newSignDate(2021,5,5,true));

mTvDaySum.setText("本期连续登录\t"+signDates.size()+"\t天");
mTvMonth.setText(year+"年"+getResources().getStringArray(R.array.month_array)[month]+"\t"+dayOfMonthToday+"日");

data=newArrayList<>();
for(inti=1;i<=dayOfMonthToday;i++){
SignEntitysignEntity=newSignEntity();
if(i==dayOfMonthToday){
signEntity.setDayType(2);
}else{
signEntity.setDayType(1);
}
for(intj=0;j

4.适配器

packagecom.example.myapplication30;


importjava.util.List;

/**
*SignAdapter
*CreatedbyE.Mon2016/4/21.
*/
publicclassSignAdapterextendsCalendarAdapter{
privateListdata;

publicSignAdapter(Listdata){
this.data=data;
}

@Override
publicSignView.DayTypegetType(intdayOfMonth){
returnSignView.DayType.valueOf(data.get(dayOfMonth-1).getDayType());
}
}

5.自定义view

packagecom.example.myapplication30;


importandroid.content.Context;
importandroid.graphics.Bitmap;
importandroid.graphics.BitmapFactory;
importandroid.graphics.BitmapShader;
importandroid.graphics.Canvas;
importandroid.graphics.Color;
importandroid.graphics.ComposeShader;
importandroid.graphics.LinearGradient;
importandroid.graphics.Paint;
importandroid.graphics.Path;
importandroid.graphics.PorterDuff;
importandroid.graphics.RadialGradient;
importandroid.graphics.Rect;
importandroid.graphics.Shader;
importandroid.graphics.SweepGradient;
importandroid.util.AttributeSet;
importandroid.view.MotionEvent;
importandroid.view.View;


importjava.util.Calendar;

/**
*签到日历控件
*CreatedbyE.Mon2016/4/20.
*/
publicclassSignViewextendsView{
privatestaticfinalString[]WEEK_MARK={"一","二","三","四","五","六","日"};

privatestaticfinalintMAX_COLUMN=7;
/**
*周内
*/
privatestaticfinalintCOLOR_MARKER_WEEKDAY=0xFF999999;
privatestaticfinalintCOLOR_MARKER_WEEKEND=0xFF1B89CD;
/**
*已签到背景色
*/
//privatestaticfinalintCOLOR_BACKGROUND_HIGHLIGHT=0xFFFF0000;
/**
*未签到背景色
*/
privatestaticfinalintCOLOR_BACKGROUND_NORMAL=0xFF9C9C9C;
/**
*等待签到背景色
*/
privatestaticfinalintCOLOR_BACKGROUND_WAIT=0xFFFE7471;
/**
*已签到文字颜色
*/
privatestaticfinalintCOLOR_TEXT_HIGHLIGHT=0xFFFFFFFF;
/**
*未签到文字颜色
*/
privatestaticfinalintCOLOR_TEXT_NORMAL=0xFF606060;
///**
//*不可用文字颜色
//*/
//privatestaticfinalintCOLOR_TEXT_DISABLED=0xFFD4D4D4;

privatestaticfinalintMARKER_TEXT_SIZE=40;
privatestaticfinalintCELL_TEXT_SIZE=40;

privatestaticfinalintVERTICAL_SPACE=51;
privatestaticfinalintVERTICAL_MARGIN=62;
privatestaticfinalintHORIZONTAL_MARGIN=39;
privatestaticfinalintCELL_SIZE=80;
privatestaticfinalintWAIT_LINE_SIZE=14;

privateintdayOfMonthToday;
privateintmarkerTextY;
privateintverticalCellTop;
privateintsumDayOfMonth;
privateintdaysOfFirstWeek;
privateinthorizontalSpace;
privateintdeltaTextCellY;
privateintdeltaTextMarkerY;

privateintverticalSpace;
privateintverticalMargin;
privateinthorizontalMargin;
privateintcellSize;
privateintwaitLineSize;

privatePathwaitPath;
privateRectwaitRect;
privatePaintpaintWeekday;
privatePaintpaintWeekend;
privatePaintpaintTextNormal;
privatePaintpaintTextHighlight;
privatePaintpaintBackgroundWait;
privatePaintpaintBackgroundNormal;
privatePaintpaintBackgroundHighlight;
privateCalendarAdapteradapter;

publicSignView(Contextcontext){
this(context,null);
}

publicSignView(Contextcontext,AttributeSetattrs){
this(context,attrs,-1);
}

publicSignView(Contextcontext,AttributeSetattrs,intdefStyleAttr){
super(context,attrs,defStyleAttr);
initResolution();
initPaint();
initData();
}

privatevoidinitResolution(){
//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;

}

privatevoidinitPaint(){
//intmarkerTextSize=resolutionUtil.formatVertical(MARKER_TEXT_SIZE);
//intcellTextSize=resolutionUtil.formatVertical(CELL_TEXT_SIZE);
intmarkerTextSize=MARKER_TEXT_SIZE;
intcellTextSize=CELL_TEXT_SIZE;

paintWeekday=newPaint();
paintWeekday.setAntiAlias(true);
paintWeekday.setColor(COLOR_MARKER_WEEKDAY);
paintWeekday.setTextSize(markerTextSize);
paintWeekday.setTextAlign(Paint.Align.CENTER);

paintWeekend=newPaint();
paintWeekend.setAntiAlias(true);
paintWeekend.setColor(COLOR_MARKER_WEEKEND);
paintWeekend.setTextSize(markerTextSize);
paintWeekend.setTextAlign(Paint.Align.CENTER);

paintTextNormal=newPaint();
paintTextNormal.setAntiAlias(true);
paintTextNormal.setColor(COLOR_TEXT_NORMAL);
paintTextNormal.setTextSize(cellTextSize);
paintTextNormal.setTextAlign(Paint.Align.CENTER);

paintTextHighlight=newPaint();
paintTextHighlight.setAntiAlias(true);
paintTextHighlight.setColor(COLOR_TEXT_HIGHLIGHT);
paintTextHighlight.setTextSize(cellTextSize);
paintTextHighlight.setTextAlign(Paint.Align.CENTER);

paintBackgroundWait=newPaint();
paintBackgroundWait.setAntiAlias(true);
paintBackgroundWait.setColor(COLOR_BACKGROUND_WAIT);
paintBackgroundWait.setStrokeWidth(2);
paintBackgroundWait.setStyle(Paint.Style.STROKE);

paintBackgroundNormal=newPaint();
paintBackgroundNormal.setAntiAlias(true);
paintBackgroundNormal.setColor(COLOR_BACKGROUND_NORMAL);
paintBackgroundNormal.setStrokeWidth(2);
paintBackgroundNormal.setStyle(Paint.Style.STROKE);

paintBackgroundHighlight=newPaint();
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};
//Shadershader1=newLinearGradient(100,850,600,850,colors,position,Shader.TileMode.CLAMP);
//paintBackgroundHighlight.setShader(shader1);
//设置背景图片
/*Bitmapplaceholder=BitmapFactory.decodeResource(getResources(),R.mipmap.small);
Shadershader1=newBitmapShader(placeholder,Shader.TileMode.CLAMP,Shader.TileMode.CLAMP);
paintBackgroundHighlight.setShader(shader1);*/


}

privatevoidinitData(){
Paint.FontMetricsIntfmiMarker=paintWeekday.getFontMetricsInt();
deltaTextMarkerY=-(fmiMarker.bottom-fmiMarker.top)/2-fmiMarker.top;
markerTextY=verticalMargin+cellSize/2;

Paint.FontMetricsIntfmiCell=paintTextNormal.getFontMetricsInt();
deltaTextCellY=-(fmiCell.bottom-fmiCell.top)/2-fmiCell.top;
verticalCellTop=verticalMargin+cellSize;

CalendarcalendarToday=Calendar.getInstance();
dayOfMonthToday=calendarToday.get(Calendar.DAY_OF_MONTH);
intdayOfWeek;
sumDayOfMonth=calendarToday.getActualMaximum(Calendar.DAY_OF_MONTH);

CalendarcalendarFirstDay=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;
}

privatevoidcreateWaitBackground(inttopX,inttopY){
waitPath=newPath();
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=newRect(topX,topY,topX+cellSize,topY+cellSize);
}

@Override
protectedvoidonSizeChanged(intw,inth,intoldw,intoldh){
super.onSizeChanged(w,h,oldw,oldh);
horizontalSpace=(w-MAX_COLUMN*cellSize-horizontalMargin*2)/(MAX_COLUMN-1);
}

@Override
publicvoiddraw(Canvascanvas){
super.draw(canvas);
drawWeekMark(canvas);
drawCellsBackground(canvas);
drawCells(canvas);
}

privatevoiddrawWeekMark(Canvascanvas){
inty=markerTextY+deltaTextMarkerY;
for(inti=0;i<7;i++){
intx=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);
}
}
}

privatevoiddrawCellsBackground(Canvascanvas){
for(inti=1;i<=dayOfMonthToday;i++){
drawCellBackground(canvas,i,getColumnIndex(i),getRowIndex(i));
}
}

/**
*根据行列序号绘制日期背景
*
*@paramcanvas画布
*@paramdayOfMonth日期
*@paramcolumn列序号
*@paramrow行序号
*/
privatevoiddrawCellBackground(Canvascanvas,intdayOfMonth,intcolumn,introw){
intx=horizontalMargin+column*(horizontalSpace+cellSize)
+cellSize/2;
inty=verticalCellTop+verticalSpace*(row+1)+cellSize*row+cellSize/2;
if(adapter!=null){
DayTypedayType=adapter.getType(dayOfMonth);
switch(dayType){
caseWAITING:
if(waitPath==null){
createWaitBackground(x-cellSize/2,y-cellSize/2);
}
canvas.drawPath(waitPath,paintBackgroundWait);
break;
caseSIGNED:
//canvas.drawCircle(x,y,cellSize/2,paintBackgroundHighlight);
//canvas.drawRect(x-60,y-60,x+60,y+60,paintBackgroundHighlight);//正方形
//Bitmapplaceholder=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);
}
}

privatevoiddrawCells(Canvascanvas){
for(inti=1;i<=sumDayOfMonth;i++){
drawCell(canvas,i,getColumnIndex(i),getRowIndex(i));
}
}

/**
*根据行列序号绘制日期
*
*@paramcanvas画布
*@paramdayOfMonth日期
*@paramcolumn列序号
*@paramrow行序号
*/
privatevoiddrawCell(Canvascanvas,intdayOfMonth,intcolumn,introw){
intx=horizontalMargin+column*(horizontalSpace+cellSize)
+cellSize/2;
inty=verticalCellTop+verticalSpace*(row+1)+cellSize*row+cellSize/2
+deltaTextCellY;
if(adapter!=null&&dayOfMonth<=dayOfMonthToday){
DayTypedayType=adapter.getType(dayOfMonth);
Paintpaint;
switch(dayType){
caseSIGNED:
paint=paintTextHighlight;
break;
default:
paint=paintTextNormal;
break;
}
canvas.drawText(String.valueOf(dayOfMonth),x,y,paint);
}else{
canvas.drawText(String.valueOf(dayOfMonth),x,y,paintTextNormal);
}
}

/**
*获取列序号
*
*@paramdayOfMonth日期
*@return列序号
*/
privateintgetColumnIndex(intdayOfMonth){
Calendarcalendar=Calendar.getInstance();
calendar.set(Calendar.DAY_OF_MONTH,dayOfMonth);
intdayOfWeek=calendar.get(Calendar.DAY_OF_WEEK);
if(dayOfWeek==Calendar.SUNDAY){
dayOfWeek=6;
}else{
dayOfWeek=dayOfWeek-2;
}
returndayOfWeek;
}

/**
*获取行序号
*
*@paramdayOfMonth日期
*@return行序号
*/
privateintgetRowIndex(intdayOfMonth){
floatweight=(dayOfMonth-daysOfFirstWeek)/(MAX_COLUMN*1f);
doublerowIndexDouble=Math.abs(Math.ceil(weight));
return(int)rowIndexDouble;
}

@Override
publicbooleanonTouchEvent(MotionEventevent){
if(event.getAction()==MotionEvent.ACTION_UP){
floatx=event.getX();
floaty=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();
}
}
}
}
}
returntrue;
}

publicvoidsetAdapter(CalendarAdapteradapter){
this.adapter=adapter;
this.invalidate();
}

publicintgetDayOfMonthToday(){
returndayOfMonthToday;
}

publicvoidnotifyDataSetChanged(){
invalidate();
}

privateOnTodayClickListeneronTodayClickListener;

publicvoidsetOnTodayClickListener(OnTodayClickListeneronTodayClickListener){
this.onTodayClickListener=onTodayClickListener;
}

publicinterfaceOnTodayClickListener{
voidonTodayClick();
}

publicenumDayType{
/**
*已签到状态,时间已过
*/
SIGNED(0),
/**
*未签到状态,时间已过
*/
UNSIGNED(1),
/**
*等待状态,即当日还未签到
*/
WAITING(2),
/**
*不可达到状态,未到时间
*/
UNREACHABLE(3),
/**
*不可用状态,非当前月份
*/
DISABLED(4);

privateintvalue;

DayType(intvalue){
this.value=value;
}

publicintgetValue(){
returnvalue;
}

publicstaticDayTypevalueOf(intvalue){
switch(value){
case0:
returnSIGNED;
case1:
returnUNSIGNED;
case2:
returnWAITING;
case3:
returnUNREACHABLE;
case4:
returnDISABLED;
default:
returnDISABLED;
}
}
}
}

以上是“Android如何自定义view实现日历打卡签到”这篇文章的所有内容,感谢各位的阅读!希望分享的内容对大家有帮助,更多相关知识,欢迎关注恰卡编程网行业资讯频道!

发布于 2021-05-10 20:35:25
分享
海报
166
上一篇:php如何获取当月第几天 下一篇:C语言如何实现简易文本编辑器
目录

    推荐阅读

    忘记密码?

    图形验证码