标签:
实现一个如图所示的控件,包括两部分,左边的饼状图和中间的两个小方块,及右边的两行文字
实现起来比较简单,只是一些绘图API的调用
核心代码在onDraw函数里边,,对静态控件进行绘制即可
@Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); /*饼状图的x坐标*/ float centreX= getWidth()/5; /*饼状图的y坐标*/ float centreY= getHeight()/2; /*文字的大小*/ float textSize=getHeight()/7; float width=(float)getWidth(); float height=(float)getHeight(); /*中间小正方形边长的一半*/ float halfSmallRec =((float)getHeight())*3/70; percent =((float) mBigBallNumber)/(mBigBallNumber + mSmallBallNumber); /*求饼状图的半径*/ radius= Math.min(getWidth() * 1 / 8, getHeight() * 10 / 35); /*构建一个正方形,饼状图是这个正方形的内切圆*/ rectf=new RectF((int)(centreX-radius),(int)(centreY-radius),(int)(centreX+radius),(int)(centreY+radius)); /*设置饼状图画笔的颜色,先绘制大球占的比例*/ piePaint.setColor(mBigBallColor); /*The arc is drawn clockwise. An angle of 0 degrees correspond to the * geometric angle of 0 degrees (3 o‘clock on a watch.)*/ /*drawArc(RectF oval, float startAngle, float sweepAngle, boolean useCenter,Paint paint)*/ /*绘制大球的扇形图,float startAngle起始角度的0度的位置在3点钟方向 * 因此大球的扇形图要从12点钟开始绘制,所以起始角度为270度*/ canvas.drawArc(rectf, 270, 360 * percent, true, piePaint); /*换种颜色,开始绘制小球占的饼状图*/ piePaint.setColor(mSmallBallColor); /*起始角度就是12点钟加上360度乘以大球占的比例,12点钟转换为起始角度为270度*/ canvas.drawArc(rectf, 270 + 360 * percent, 360 - 360 * percent, true, piePaint); /*颜色更改为大球的颜色*/ piePaint.setColor(mBigBallColor); /*绘制上边的小方块,也就是大球的方块*/ canvas.drawRect(width * 2 / 5 - halfSmallRec, height* 23/ 60 - halfSmallRec, width * 2 / 5 + halfSmallRec, height *23/ 60 + halfSmallRec, piePaint); /*更改画笔颜色为小球颜色*/ piePaint.setColor(mSmallBallColor); /*绘制下边的小方块即小球的小方块*/ canvas.drawRect(width * 2 / 5 - halfSmallRec, height * 37 / 60 - halfSmallRec, width * 2 / 5 + halfSmallRec, height * 37 / 60 + halfSmallRec, piePaint); /*开始绘制文字,先设置文字颜色*/ textPaint.setColor(getResources().getColor(typedValue.resourceId)); /*设置问题大小*/ textPaint.setTextSize(textSize); /*大球数量*/ String strBig = strBigBallName + mBigBallNumber; /*测量文字宽度*/ float textBigWidth =textPaint.measureText(strBig); Paint.FontMetrics fontMetrics=textPaint.getFontMetrics(); /*绘制上边大球数量*/ canvas.drawText(strBig, width * 9 / 20 + textBigWidth / 2, height *23/ 60 - fontMetrics.top / 3, textPaint); /*小球数量*/ String strSmall = strSmallBallName + mSmallBallNumber; /*测量文字宽度*/ float textUnderWidth=textPaint.measureText(strSmall); /*绘制下边的小球数量*/ canvas.drawText(strSmall,width*9/20+textUnderWidth/2,height*37/60-fontMetrics.top/3,textPaint); /*更改画笔颜色,开始绘制百分比*/ textPaint.setColor(getResources().getColor(R.color.half_transparent)); String strBigPercent =" ("+ mPercentBigBall +")"; /*测量大球百分比文字宽度*/ float bigPercent =textPaint.measureText(strBigPercent); /*drawText(String text, float x, float y, Paint paint) * 绘制文字的API,四个参数分别是文字内容,起始绘制x坐标,起始绘制y坐标,画笔 * 以为设置了居中绘制,因此穿进去的xy坐标为文字的中心点*/ canvas.drawText(strBigPercent, width * 9 / 20+ textBigWidth + bigPercent /2, height*23 / 60-fontMetrics.top*1/3, textPaint); /*同样的道理绘制小球的百分比*/ String strSmallPercent =" ("+ mPercentSmallBall +")"; float smallPercent =textPaint.measureText(strSmallPercent); canvas.drawText(strSmallPercent,width*9/20+textUnderWidth+ smallPercent /2,height*37/60-fontMetrics.top/3,textPaint); }Canvas 绘制文本时,使用FontMetrics对象,计算位置的坐标。参考:http://blog.csdn.net/tianjf0514/article/details/7642656
设置文字绘制以中心为起点开始绘制
textPaint.setTextAlign(Paint.Align.CENTER);
x的坐标好计算,y坐标需要按需使用FontMetrics几个属性即可
完整代码如下:
public class PieHalfView extends View { /*左边饼状图的画笔*/ private Paint piePaint; /*右边文字的画笔*/ private Paint textPaint; /*饼状图的半径*/ private float radius; private RectF rectf; /*饼状图中第一个扇形占整个圆的比例*/ private float percent; /*深浅两种颜色*/ private int mBigBallColor, mSmallBallColor; /*大小球的数量*/ private int mBigBallNumber; private int mSmallBallNumber; /*大小球所占的百分比*/ private String mPercentBigBall; private String mPercentSmallBall; /*动态获取属性*/ private TypedValue typedValue; /*中间的文字信息*/ private String strBigBallName; private String strSmallBallName; public PieHalfView(Context context) { super(context); init(context); } public PieHalfView(Context context, AttributeSet attrs) { super(context, attrs); init(context); } public PieHalfView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); init(context); } private void init(Context context) { /*设置饼状图画笔*/ piePaint =new Paint(); piePaint.setAntiAlias(true); piePaint.setStyle(Paint.Style.FILL); /*设置文字画笔*/ textPaint=new Paint(); textPaint.setStyle(Paint.Style.STROKE); textPaint.setAntiAlias(true); textPaint.setTextAlign(Paint.Align.CENTER); /*下边设置一些默认的值,如果调用者没有传值进来的话,用这些默认值*/ mBigBallColor = 0xFF9CCA5D; mSmallBallColor =0xFF5F7048; /*TypedValue:Container for a dynamically typed data value. Primarily used with Resources for holding resource values.*/ typedValue=new TypedValue(); context.getTheme().resolveAttribute(R.attr.maintextclor,typedValue,true); mBigBallNumber =1; mSmallBallNumber =3; mPercentBigBall ="40%"; mPercentSmallBall ="60%"; strBigBallName =getResources().getString(R.string.big); strSmallBallName =getResources().getString(R.string.small); } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); /*饼状图的x坐标*/ float centreX= getWidth()/5; /*饼状图的y坐标*/ float centreY= getHeight()/2; /*文字的大小*/ float textSize=getHeight()/7; float width=(float)getWidth(); float height=(float)getHeight(); /*中间小正方形边长的一半*/ float halfSmallRec =((float)getHeight())*3/70; percent =((float) mBigBallNumber)/(mBigBallNumber + mSmallBallNumber); /*求饼状图的半径*/ radius= Math.min(getWidth() * 1 / 8, getHeight() * 10 / 35); /*构建一个正方形,饼状图是这个正方形的内切圆*/ rectf=new RectF((int)(centreX-radius),(int)(centreY-radius),(int)(centreX+radius),(int)(centreY+radius)); /*设置饼状图画笔的颜色,先绘制大球占的比例*/ piePaint.setColor(mBigBallColor); /*The arc is drawn clockwise. An angle of 0 degrees correspond to the * geometric angle of 0 degrees (3 o'clock on a watch.)*/ /*drawArc(RectF oval, float startAngle, float sweepAngle, boolean useCenter,Paint paint)*/ /*绘制大球的扇形图,float startAngle起始角度的0度的位置在3点钟方向 * 因此大球的扇形图要从12点钟开始绘制,所以起始角度为270度*/ canvas.drawArc(rectf, 270, 360 * percent, true, piePaint); /*换种颜色,开始绘制小球占的饼状图*/ piePaint.setColor(mSmallBallColor); /*起始角度就是12点钟加上360度乘以大球占的比例,12点钟转换为起始角度为270度*/ canvas.drawArc(rectf, 270 + 360 * percent, 360 - 360 * percent, true, piePaint); /*颜色更改为大球的颜色*/ piePaint.setColor(mBigBallColor); /*绘制上边的小方块,也就是大球的方块*/ canvas.drawRect(width * 2 / 5 - halfSmallRec, height* 23/ 60 - halfSmallRec, width * 2 / 5 + halfSmallRec, height *23/ 60 + halfSmallRec, piePaint); /*更改画笔颜色为小球颜色*/ piePaint.setColor(mSmallBallColor); /*绘制下边的小方块即小球的小方块*/ canvas.drawRect(width * 2 / 5 - halfSmallRec, height * 37 / 60 - halfSmallRec, width * 2 / 5 + halfSmallRec, height * 37 / 60 + halfSmallRec, piePaint); /*开始绘制文字,先设置文字颜色*/ textPaint.setColor(getResources().getColor(typedValue.resourceId)); /*设置问题大小*/ textPaint.setTextSize(textSize); /*大球数量*/ String strBig = strBigBallName + mBigBallNumber; /*测量文字宽度*/ float textBigWidth =textPaint.measureText(strBig); Paint.FontMetrics fontMetrics=textPaint.getFontMetrics(); /*绘制上边大球数量*/ canvas.drawText(strBig, width * 9 / 20 + textBigWidth / 2, height *23/ 60 - fontMetrics.top / 3, textPaint); /*小球数量*/ String strSmall = strSmallBallName + mSmallBallNumber; /*测量文字宽度*/ float textUnderWidth=textPaint.measureText(strSmall); /*绘制下边的小球数量*/ canvas.drawText(strSmall,width*9/20+textUnderWidth/2,height*37/60-fontMetrics.top/3,textPaint); /*更改画笔颜色,开始绘制百分比*/ textPaint.setColor(getResources().getColor(R.color.half_transparent)); String strBigPercent =" ("+ mPercentBigBall +")"; /*测量大球百分比文字宽度*/ float bigPercent =textPaint.measureText(strBigPercent); /*drawText(String text, float x, float y, Paint paint) * 绘制文字的API,四个参数分别是文字内容,起始绘制x坐标,起始绘制y坐标,画笔 * 以为设置了居中绘制,因此穿进去的xy坐标为文字的中心点*/ canvas.drawText(strBigPercent, width * 9 / 20+ textBigWidth + bigPercent /2, height*23 / 60-fontMetrics.top*1/3, textPaint); /*同样的道理绘制小球的百分比*/ String strSmallPercent =" ("+ mPercentSmallBall +")"; float smallPercent =textPaint.measureText(strSmallPercent); canvas.drawText(strSmallPercent,width*9/20+textUnderWidth+ smallPercent /2,height*37/60-fontMetrics.top/3,textPaint); } public void setPercent(float percent1){ this.percent =percent1; invalidate(); } public void setColor(int mBigBallColor,int mSmallBallColor){ this.mBigBallColor =mBigBallColor; this.mSmallBallColor =mSmallBallColor; invalidate(); } public void setOverRunner(String bigPecent, String smallPercent, int big, int small, int bigColor, int smallColor){ this.mPercentBigBall = bigPecent; this.mPercentSmallBall = smallPercent; this.mBigBallNumber = big; this.mSmallBallNumber = small; this.mBigBallColor = bigColor; this.mSmallBallColor = smallColor; invalidate(); } }
标签:
原文地址:http://blog.csdn.net/wangshihui512/article/details/51354502