本文实例为大家分享了Android地铁显示牌的具体代码,供大家参考,具体内容如下
预览效果
目录
SubwayBoardView.java
public class SubwayBoardView extends View { private Paint bgPaint,tbPaint,centerBgPaint,centerRingPaint,centerCirclePaint,centerCircleRingPaint,noStationPaint,stationPaint,doorPaint; private TextPaint centerTextPaint,stationTextPaint,currentStationTextPaint,doorTextPaint; private float barHeight = DensityUtil.dp2Px(getContext(),20); private float centerCircleWidth; private float centerRingWidth; private float centerCircleRingStrokeWidth = DensityUtil.dp2Px(getContext(),5); private float centerRingStrokeWidth = DensityUtil.dp2Px(getContext(),36); private float centerCircleRingSweepAngle = 0f; private ObjectAnimator centerCircleRingAnim; private List<String> noStationStrs = new ArrayList<>(); private List<String> stationStrs = new ArrayList<>(); private String currentStationStrs = "杭州站"; private Bitmap doorBitmap; private Camera camera; public SubwayBoardView(Context context) { super(context); initView(); } public SubwayBoardView(Context context,@Nullable AttributeSet attrs) { super(context,attrs); initView(); } public SubwayBoardView(Context context,@Nullable AttributeSet attrs,int defStyleAttr) { super(context,attrs,defStyleAttr); initView(); } private void initView() { //全背景 bgPaint = new Paint(Paint.ANTI_ALIAS_FLAG); bgPaint.setStyle(Paint.Style.FILL); bgPaint.setColor(Color.parseColor("#85919a")); //上下边栏 tbPaint = new Paint(Paint.ANTI_ALIAS_FLAG); tbPaint.setStyle(Paint.Style.FILL); tbPaint.setColor(Color.parseColor("#c21b2c")); //中间栏 centerBgPaint = new Paint(Paint.ANTI_ALIAS_FLAG); centerBgPaint.setStyle(Paint.Style.FILL); centerBgPaint.setColor(Color.parseColor("#92a3d1")); //中间空白圆环区域 centerRingPaint = new Paint(Paint.ANTI_ALIAS_FLAG); centerRingPaint.setStyle(Paint.Style.STROKE); centerRingPaint.setStrokeWidth(centerRingStrokeWidth); centerRingPaint.setColor(Color.parseColor("#85919a")); //中间圆 centerCirclePaint = new Paint(Paint.ANTI_ALIAS_FLAG); centerCirclePaint.setStyle(Paint.Style.FILL); centerCirclePaint.setColor(Color.parseColor("#c21b2c")); //中间圆边上的圆环 centerCircleRingPaint = new Paint(Paint.ANTI_ALIAS_FLAG); centerCircleRingPaint.setStyle(Paint.Style.STROKE); centerCircleRingPaint.setStrokeWidth(centerCircleRingStrokeWidth); centerCircleRingPaint.setStrokeCap(Paint.Cap.ROUND); centerCircleRingPaint.setColor(Color.parseColor("#6e8ca6")); //中间文字 centerTextPaint = new TextPaint(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,Color.parseColor("#6e8ca6")); centerTextPaint.setTextSize(DensityUtil.sp2px(getContext(),24)); //未到达的站 noStationPaint = new Paint(Paint.ANTI_ALIAS_FLAG); noStationPaint.setStyle(Paint.Style.FILL_AND_STROKE); noStationPaint.setColor(Color.parseColor("#c21b2c")); //未到站文字 stationTextPaint = new TextPaint(Paint.ANTI_ALIAS_FLAG); stationTextPaint.setStyle(Paint.Style.FILL); stationTextPaint.setColor(Color.parseColor("#333333")); stationTextPaint.setTextAlign(Paint.Align.CENTER); stationTextPaint.setShadowLayer(3,Color.parseColor("#6e8ca6")); stationTextPaint.setTextSize(DensityUtil.sp2px(getContext(),18)); noStationStrs.add("宁波站"); noStationStrs.add("上虞站"); noStationStrs.add("绍兴站"); //已到达的站 stationPaint = new Paint(Paint.ANTI_ALIAS_FLAG); stationPaint.setStyle(Paint.Style.FILL_AND_STROKE); stationPaint.setColor(Color.parseColor("#7586b2")); stationStrs.add("南京站"); stationStrs.add("苏州站"); stationStrs.add("上海站"); //到站文字 currentStationTextPaint = new TextPaint(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 = new Paint(Paint.ANTI_ALIAS_FLAG); doorBitmap = BitmapFactory.decodeResource(getResources(),R.mipmap.open_door); doorTextPaint = new TextPaint(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 = new Camera(); } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); int width = getWidth(); int height = getHeight(); int centerX = width / 2; int centerY = 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,width,height,bgPaint); //上下栏 canvas.drawRect(0,barHeight,tbPaint); canvas.drawRect(0,height - barHeight,tbPaint); //中间圆环空白区域 canvas.drawCircle(centerX,centerY,centerRingWidth,centerRingPaint); //中间栏 float centerLineT = barHeight + DensityUtil.dp2Px(getContext(),10); float centerLineB = height - barHeight - DensityUtil.dp2Px(getContext(),10); canvas.drawRect(0,centerLineT,centerLineB,centerBgPaint); //中间圆 canvas.drawCircle(centerX,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.FontMetrics fontMetrics = centerTextPaint.getFontMetrics(); float dx = (fontMetrics.bottom - fontMetrics.top) / 2 - fontMetrics.bottom; canvas.drawText(currentStationStrs,centerX,centerY + dx,centerTextPaint); //未到站 float stationStart = DensityUtil.dp2Px(getContext(),20); float stationWidth = DensityUtil.dp2Px(getContext(),40); float stationPadding = DensityUtil.dp2Px(getContext(),20); for (int i = 0; i < noStationStrs.size(); i++) { canvas.drawPath(getStationView(stationStart + (stationWidth + stationPadding) * i,stationWidth,centerLineB),noStationPaint); //保存画布 canvas.save(); String stationStr = noStationStrs.get(i); Paint.FontMetrics fm = stationTextPaint.getFontMetrics(); //文字高度 float fontHeight = (fm.bottom - fm.top) * stationStr.length(); //显示高度 float showHeigth = centerLineB - centerLineT; //移动画布 canvas.translate(stationStart + (stationWidth + stationPadding) * i + stationWidth / 3,centerLineT + (showHeigth - fontHeight) / 2); float strWidth = stationTextPaint.measureText(stationStr) / stationStr.length(); StaticLayout staticLayout; if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { staticLayout = StaticLayout.Builder.obtain(stationStr,stationStr.length(),(int) strWidth).build(); } else { staticLayout = new StaticLayout(stationStr,(int) strWidth,Layout.Alignment.ALIGN_CENTER,1,true); } //绘制 staticLayout.draw(canvas); //还原画布 canvas.translate(-stationStart + (stationWidth + stationPadding) * i,-centerLineT); canvas.restore(); } //已过站 float stationEnd = getWidth() - DensityUtil.dp2Px(getContext(),20) - stationWidth; for (int i = 0; i < stationStrs.size(); i++) { canvas.drawPath(getStationView(stationEnd - (stationWidth + stationPadding) * i,stationPaint); //保存画布 canvas.save(); String stationStr = noStationStrs.get(i); Paint.FontMetrics fm = stationTextPaint.getFontMetrics(); //文字高度 float fontHeight = (fm.bottom - fm.top) * stationStr.length(); //显示高度 float showHeigth = centerLineB - centerLineT; //移动画布 canvas.translate(stationEnd - (stationWidth + stationPadding) * i + stationWidth / 3,-centerLineT); canvas.restore(); } //到达站 String curentStr = "停靠站" + currentStationStrs; float fontwidth = stationTextPaint.measureText(curentStr) / curentStr.length(); float pointX = centerX - centerRingWidth - fontwidth * 3 - DensityUtil.dp2Px(getContext(),26); Paint.FontMetrics fm = stationTextPaint.getFontMetrics(); float pointY = centerLineT + ((centerLineB - centerLineT) - (fm.bottom - fm.top) * 2) / 2; canvas.save(); canvas.translate(pointX,pointY); StaticLayout staticLayout; if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { staticLayout = StaticLayout.Builder.obtain(curentStr,curentStr.length(),(int) (fontwidth * 3)).build(); } else { staticLayout = new StaticLayout(curentStr,(int) (fontwidth * 3),true); } //绘制 staticLayout.draw(canvas); canvas.translate(-pointX,-centerLineT); canvas.restore(); //开门提示 String primt = "注意开门"; float doorTextWidth = doorTextPaint.measureText(primt); Paint.FontMetrics doorTextFm = doorTextPaint.getFontMetrics(); float doorTextheight = doorTextFm.bottom - doorTextFm.top; float dy = doorTextheight / 2 - doorTextFm.bottom; int doorTextLeft = (int) (centerX + centerRingWidth + DensityUtil.dp2Px(getContext(),26)); Rect rect = new Rect(); 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); } /** * 获取站信息 * * @param pl * @param width * @param centerLineT * @param centerLineB * @return */ private Path getStationView(float pl,float width,float centerLineT,float centerLineB) { float pt = centerLineT; float pr = pl + width; float pb = centerLineB; float r = (pr - pl) / 3; Path path = new Path(); 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,pl,pt); path.close(); return path; } public void setCenterCircleRingSweepAngle(float centerCircleRingSweepAngle) { this.centerCircleRingSweepAngle = centerCircleRingSweepAngle; invalidate(); } /** * 开始中间圆动画 */ public void animCenterCircleRing() { if (null == centerCircleRingAnim) { centerCircleRingAnim = ObjectAnimator.ofFloat(this,"centerCircleRingSweepAngle",0f,360f); centerCircleRingAnim.setDuration(3000); centerCircleRingAnim.setInterpolator(new LinearInterpolator()); centerCircleRingAnim.setRepeatCount(ValueAnimator.INFINITE); centerCircleRingAnim.setRepeatMode(ValueAnimator.RESTART); } centerCircleRingAnim.start(); } /** * 停止 */ public void stopAnimCenterCircleRing() { if (null != centerCircleRingAnim) { centerCircleRingAnim.cancel(); } setCenterCircleRingSweepAngle(0); } }原文链接:https://www.f2er.com/android/534596.html