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); List signDates=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(List data){ 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实现日历打卡签到”这篇文章的所有内容,感谢各位的阅读!希望分享的内容对大家有帮助,更多相关知识,欢迎关注恰卡编程网行业资讯频道!
推荐阅读
-
我的世界windows版怎么下载手机版
-
android(如何快速开发框架 小米note开发版MIUI,安卓6.0,怎么安装Xposed框架)
稳定版,你必须先根除。你上网搜索安卓可以叫别人s框架,对方可以把框架做成jar包,把这个jar包加载到项目目录的libs文件中使...
-
android(studio 虚拟机启动不了 android studio可以当模拟器用吗)
androidstudio可以当模拟器用吗?AmdCUP引导模拟器有点复杂。雷电模拟器上的抖音怎么登录不上?不是,闪电模拟调用...
-
从实践中学习手机抓包与数据分析(android 手机抓包app)
android手机抓包app?netcapture抓包精灵app(手机抓包工具)又名sslcapture,是什么专业的安卓手机抓...
-
android(studio全局搜索 android studio怎么看app界面)
androidstudio怎么看app界面?在设备桌面点击运用直接进入到App界面,就也可以参与其他你的操作了。android-...
-
怎么把android框架源代码拉到本地(android studio如何运行别人的源代码)
androidstudio如何运行别人的源代码?androidstudio点击刚建在列表中你选择导入module,导入即可在用...
-
android(studio2022年使用教程 怎么安装Android studio详细教程)
怎么安装Androidstudio详细教程?androidstudio中haxm直接安装的方法追加:1、简单的方法打开Andr...
-
怎么使用Android基准配置文件Baseline Profile方案提升启动速度
怎么使用Android基准配置文件Baseline Profile方案提升启动速度...
-
HTML5如何实现禁止android视频另存为
HTML5如何实现禁止android视频另存为今天小编给大家分享一...
-
学java好还是学php好?