Android自定义View实现地铁显示牌效果
本文实例为大家分享了Android地铁显示牌的具体代码,供大家参考,具体内容如下
预览效果
目录
SubwayBoardView.java
代码
publicclassSubwayBoardViewextendsView{ privatePaintbgPaint,tbPaint,centerBgPaint,centerRingPaint,centerCirclePaint,centerCircleRingPaint,noStationPaint,stationPaint,doorPaint; privateTextPaintcenterTextPaint,stationTextPaint,currentStationTextPaint,doorTextPaint; privatefloatbarHeight=DensityUtil.dp2Px(getContext(),20); privatefloatcenterCircleWidth; privatefloatcenterRingWidth; privatefloatcenterCircleRingStrokeWidth=DensityUtil.dp2Px(getContext(),5); privatefloatcenterRingStrokeWidth=DensityUtil.dp2Px(getContext(),36); privatefloatcenterCircleRingSweepAngle=0f; privateObjectAnimatorcenterCircleRingAnim; privateListnoStationStrs=newArrayList<>(); privateList stationStrs=newArrayList<>(); privateStringcurrentStationStrs="杭州站"; privateBitmapdoorBitmap; privateCameracamera; publicSubwayBoardView(Contextcontext){ super(context); initView(); } publicSubwayBoardView(Contextcontext,@NullableAttributeSetattrs){ super(context,attrs); initView(); } publicSubwayBoardView(Contextcontext,@NullableAttributeSetattrs,intdefStyleAttr){ super(context,attrs,defStyleAttr); initView(); } privatevoidinitView(){ //全背景 bgPaint=newPaint(Paint.ANTI_ALIAS_FLAG); bgPaint.setStyle(Paint.Style.FILL); bgPaint.setColor(Color.parseColor("#85919a")); //上下边栏 tbPaint=newPaint(Paint.ANTI_ALIAS_FLAG); tbPaint.setStyle(Paint.Style.FILL); tbPaint.setColor(Color.parseColor("#c21b2c")); //中间栏 centerBgPaint=newPaint(Paint.ANTI_ALIAS_FLAG); centerBgPaint.setStyle(Paint.Style.FILL); centerBgPaint.setColor(Color.parseColor("#92a3d1")); //中间空白圆环区域 centerRingPaint=newPaint(Paint.ANTI_ALIAS_FLAG); centerRingPaint.setStyle(Paint.Style.STROKE); centerRingPaint.setStrokeWidth(centerRingStrokeWidth); centerRingPaint.setColor(Color.parseColor("#85919a")); //中间圆 centerCirclePaint=newPaint(Paint.ANTI_ALIAS_FLAG); centerCirclePaint.setStyle(Paint.Style.FILL); centerCirclePaint.setColor(Color.parseColor("#c21b2c")); //中间圆边上的圆环 centerCircleRingPaint=newPaint(Paint.ANTI_ALIAS_FLAG); centerCircleRingPaint.setStyle(Paint.Style.STROKE); centerCircleRingPaint.setStrokeWidth(centerCircleRingStrokeWidth); centerCircleRingPaint.setStrokeCap(Paint.Cap.ROUND); centerCircleRingPaint.setColor(Color.parseColor("#6e8ca6")); //中间文字 centerTextPaint=newTextPaint(Paint.ANTI_ALIAS_FLAG); centerTextPaint.setStyle(Paint.Style.FILL); centerTextPaint.setFakeBoldText(true); centerTextPaint.setColor(Color.parseColor("#333333")); centerTextPaint.setTextAlign(Paint.Align.CENTER); centerTextPaint.setShadowLayer(3,3,3,Color.parseColor("#6e8ca6")); centerTextPaint.setTextSize(DensityUtil.sp2px(getContext(),24)); //未到达的站 noStationPaint=newPaint(Paint.ANTI_ALIAS_FLAG); noStationPaint.setStyle(Paint.Style.FILL_AND_STROKE); noStationPaint.setColor(Color.parseColor("#c21b2c")); //未到站文字 stationTextPaint=newTextPaint(Paint.ANTI_ALIAS_FLAG); stationTextPaint.setStyle(Paint.Style.FILL); stationTextPaint.setColor(Color.parseColor("#333333")); stationTextPaint.setTextAlign(Paint.Align.CENTER); stationTextPaint.setShadowLayer(3,3,3,Color.parseColor("#6e8ca6")); stationTextPaint.setTextSize(DensityUtil.sp2px(getContext(),18)); noStationStrs.add("宁波站"); noStationStrs.add("上虞站"); noStationStrs.add("绍兴站"); //已到达的站 stationPaint=newPaint(Paint.ANTI_ALIAS_FLAG); stationPaint.setStyle(Paint.Style.FILL_AND_STROKE); stationPaint.setColor(Color.parseColor("#7586b2")); stationStrs.add("南京站"); stationStrs.add("苏州站"); stationStrs.add("上海站"); //到站文字 currentStationTextPaint=newTextPaint(Paint.ANTI_ALIAS_FLAG); currentStationTextPaint.setStyle(Paint.Style.FILL); currentStationTextPaint.setFakeBoldText(true); currentStationTextPaint.setColor(Color.parseColor("#3d5d9a")); currentStationTextPaint.setTextAlign(Paint.Align.LEFT); currentStationTextPaint.setTextSize(DensityUtil.sp2px(getContext(),18)); doorPaint=newPaint(Paint.ANTI_ALIAS_FLAG); doorBitmap=BitmapFactory.decodeResource(getResources(),R.mipmap.open_door); doorTextPaint=newTextPaint(Paint.ANTI_ALIAS_FLAG); doorTextPaint.setStyle(Paint.Style.FILL); doorTextPaint.setColor(Color.parseColor("#c21b2c")); doorTextPaint.setTextAlign(Paint.Align.LEFT); doorTextPaint.setTextSize(DensityUtil.sp2px(getContext(),14)); camera=newCamera(); } @Override protectedvoidonDraw(Canvascanvas){ super.onDraw(canvas); intwidth=getWidth(); intheight=getHeight(); intcenterX=width/2; intcenterY=height/2; //计算中间空白圆形宽度 if(0==centerRingWidth){ centerRingWidth=(height-DensityUtil.dp2Px(getContext(),12))*1f/2; } //计算中间圆的半径 if(0==centerCircleWidth){ centerCircleWidth=centerRingWidth-DensityUtil.dp2Px(getContext(),8); } //背景 canvas.drawRect(0,0,width,height,bgPaint); //上下栏 canvas.drawRect(0,0,width,barHeight,tbPaint); canvas.drawRect(0,height-barHeight,width,height,tbPaint); //中间圆环空白区域 canvas.drawCircle(centerX,centerY,centerRingWidth,centerRingPaint); //中间栏 floatcenterLineT=barHeight+DensityUtil.dp2Px(getContext(),10); floatcenterLineB=height-barHeight-DensityUtil.dp2Px(getContext(),10); canvas.drawRect(0,centerLineT,width,centerLineB,centerBgPaint); //中间圆 canvas.drawCircle(centerX,centerY,centerCircleWidth,centerCirclePaint); //中间圆环 if(centerCircleRingSweepAngle>0){ canvas.drawArc(centerX-centerCircleWidth-(centerCircleRingStrokeWidth/2),centerY-centerCircleWidth-(centerCircleRingStrokeWidth/2),centerX+centerCircleWidth+(centerCircleRingStrokeWidth/2),centerY+centerCircleWidth+(centerCircleRingStrokeWidth/2),-90f,centerCircleRingSweepAngle,false,centerCircleRingPaint); } //中间文字 Paint.FontMetricsfontMetrics=centerTextPaint.getFontMetrics(); floatdx=(fontMetrics.bottom-fontMetrics.top)/2-fontMetrics.bottom; canvas.drawText(currentStationStrs,centerX,centerY+dx,centerTextPaint); //未到站 floatstationStart=DensityUtil.dp2Px(getContext(),20); floatstationWidth=DensityUtil.dp2Px(getContext(),40); floatstationPadding=DensityUtil.dp2Px(getContext(),20); for(inti=0;i =Build.VERSION_CODES.M){ staticLayout=StaticLayout.Builder.obtain(stationStr,0,stationStr.length(),stationTextPaint,(int)strWidth).build(); }else{ staticLayout=newStaticLayout(stationStr,stationTextPaint,(int)strWidth,Layout.Alignment.ALIGN_CENTER,1,0,true); } //绘制 staticLayout.draw(canvas); //还原画布 canvas.translate(-stationStart+(stationWidth+stationPadding)*i,-centerLineT); canvas.restore(); } //已过站 floatstationEnd=getWidth()-DensityUtil.dp2Px(getContext(),20)-stationWidth; for(inti=0;i =Build.VERSION_CODES.M){ staticLayout=StaticLayout.Builder.obtain(stationStr,0,stationStr.length(),stationTextPaint,(int)strWidth).build(); }else{ staticLayout=newStaticLayout(stationStr,stationTextPaint,(int)strWidth,Layout.Alignment.ALIGN_CENTER,1,0,true); } //绘制 staticLayout.draw(canvas); //还原画布 canvas.translate(-stationStart+(stationWidth+stationPadding)*i,-centerLineT); canvas.restore(); } //到达站 StringcurentStr="停靠站"+currentStationStrs; floatfontwidth=stationTextPaint.measureText(curentStr)/curentStr.length(); floatpointX=centerX-centerRingWidth-fontwidth*3-DensityUtil.dp2Px(getContext(),26); Paint.FontMetricsfm=stationTextPaint.getFontMetrics(); floatpointY=centerLineT+((centerLineB-centerLineT)-(fm.bottom-fm.top)*2)/2; canvas.save(); canvas.translate(pointX,pointY); StaticLayoutstaticLayout; if(Build.VERSION.SDK_INT>=Build.VERSION_CODES.M){ staticLayout=StaticLayout.Builder.obtain(curentStr,0,curentStr.length(),stationTextPaint,(int)(fontwidth*3)).build(); }else{ staticLayout=newStaticLayout(curentStr,stationTextPaint,(int)(fontwidth*3),Layout.Alignment.ALIGN_CENTER,1,0,true); } //绘制 staticLayout.draw(canvas); canvas.translate(-pointX,-centerLineT); canvas.restore(); //开门提示 Stringprimt="注意开门"; floatdoorTextWidth=doorTextPaint.measureText(primt); Paint.FontMetricsdoorTextFm=doorTextPaint.getFontMetrics(); floatdoorTextheight=doorTextFm.bottom-doorTextFm.top; floatdy=doorTextheight/2-doorTextFm.bottom; intdoorTextLeft=(int)(centerX+centerRingWidth+DensityUtil.dp2Px(getContext(),26)); Rectrect=newRect(); rect.left=(int)(doorTextLeft+((doorTextWidth-doorBitmap.getWidth())/2)); rect.top=(int)(centerLineT+((centerLineB-centerLineT)-(doorBitmap.getHeight()+DensityUtil.dp2Px(getContext(),6)++doorTextheight))/2); rect.right=rect.left+doorBitmap.getWidth(); rect.bottom=rect.top+doorBitmap.getHeight(); //旋转 canvas.save(); camera.save(); canvas.translate(rect.left,rect.top); camera.rotateY(-45); camera.applyToCanvas(canvas); canvas.translate(-rect.left,-rect.top); camera.restore(); canvas.drawBitmap(doorBitmap,null,rect,doorPaint); canvas.restore(); canvas.drawText(primt,doorTextLeft,rect.bottom+DensityUtil.dp2Px(getContext(),6)+(doorTextheight/2)+dy,doorTextPaint); } /** *获取站信息 * *@parampl *@paramwidth *@paramcenterLineT *@paramcenterLineB *@return */ privatePathgetStationView(floatpl,floatwidth,floatcenterLineT,floatcenterLineB){ floatpt=centerLineT; floatpr=pl+width; floatpb=centerLineB; floatr=(pr-pl)/3; Pathpath=newPath(); path.moveTo(pl,pt); path.lineTo(pr,pt); path.quadTo(pr-r,pt+(pb-pt)/2,pr,pb); path.lineTo(pl,pb); path.quadTo(pl-r,pt+(pb-pt)/2,pl,pt); path.close(); returnpath; } publicvoidsetCenterCircleRingSweepAngle(floatcenterCircleRingSweepAngle){ this.centerCircleRingSweepAngle=centerCircleRingSweepAngle; invalidate(); } /** *开始中间圆动画 */ publicvoidanimCenterCircleRing(){ if(null==centerCircleRingAnim){ centerCircleRingAnim=ObjectAnimator.ofFloat(this,"centerCircleRingSweepAngle",0f,360f); centerCircleRingAnim.setDuration(3000); centerCircleRingAnim.setInterpolator(newLinearInterpolator()); centerCircleRingAnim.setRepeatCount(ValueAnimator.INFINITE); centerCircleRingAnim.setRepeatMode(ValueAnimator.RESTART); } centerCircleRingAnim.start(); } /** *停止 */ publicvoidstopAnimCenterCircleRing(){ if(null!=centerCircleRingAnim){ centerCircleRingAnim.cancel(); } setCenterCircleRingSweepAngle(0); } }
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持毛票票。
声明:本文内容来源于网络,版权归原作者所有,内容由互联网用户自发贡献自行上传,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任。如果您发现有涉嫌版权的内容,欢迎发送邮件至:czq8825#qq.com(发邮件时,请将#更换为@)进行举报,并提供相关证据,一经查实,本站将立刻删除涉嫌侵权内容。