Android自定义View实现地铁显示牌效果
程序员文章站
2022-06-06 23:35:35
本文实例为大家分享了android地铁显示牌的具体代码,供大家参考,具体内容如下
预览效果
目录
subwayboardview.java
代码
public c...
本文实例为大家分享了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, 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, 3, 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, 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); //中间栏 float centerlinet = barheight + densityutil.dp2px(getcontext(), 10); float centerlineb = 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.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, centerlinet, 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, 0, stationstr.length(), stationtextpaint, (int) strwidth).build(); } else { staticlayout = new staticlayout(stationstr, stationtextpaint, (int) strwidth, layout.alignment.align_center, 1, 0, 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, stationwidth, centerlinet, centerlineb), 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 + (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, 0, stationstr.length(), stationtextpaint, (int) strwidth).build(); } else { staticlayout = new staticlayout(stationstr, stationtextpaint, (int) strwidth, layout.alignment.align_center, 1, 0, true); } //绘制 staticlayout.draw(canvas); //还原画布 canvas.translate(-stationstart + (stationwidth + stationpadding) * i, -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, 0, curentstr.length(), stationtextpaint, (int) (fontwidth * 3)).build(); } else { staticlayout = new staticlayout(curentstr, stationtextpaint, (int) (fontwidth * 3), layout.alignment.align_center, 1, 0, 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, pt + (pb - pt) / 2, 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); } }
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。
上一篇: 武则天如此宠爱狄仁杰,背后有什么原因?
下一篇: ASP.net基础知识之常见错误分析