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<>();
privateListstationStrs=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(发邮件时,请将#更换为@)进行举报,并提供相关证据,一经查实,本站将立刻删除涉嫌侵权内容。