本文實現(xiàn)一個如圖所示的控件,包括兩部分,左邊的餅狀圖和中間的兩個小方塊,及右邊的兩行文字
站在用戶的角度思考問題,與客戶深入溝通,找到長垣網(wǎng)站設(shè)計與長垣網(wǎng)站推廣的解決方案,憑借多年的經(jīng)驗,讓設(shè)計與互聯(lián)網(wǎng)技術(shù)結(jié)合,創(chuàng)造個性化、用戶體驗好的作品,建站類型包括:網(wǎng)站制作、成都網(wǎng)站設(shè)計、企業(yè)官網(wǎng)、英文網(wǎng)站、手機端網(wǎng)站、網(wǎng)站推廣、域名注冊、網(wǎng)頁空間、企業(yè)郵箱。業(yè)務(wù)覆蓋長垣地區(qū)。
實現(xiàn)起來比較簡單,只是一些繪圖API的調(diào)用
核心代碼在onDraw函數(shù)里邊,對靜態(tài)控件進行繪制即可
@Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); /** * 餅狀圖的x坐標(biāo) */ float centreX= getWidth()/5; /** * 餅狀圖的y坐標(biāo) */ 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); /** * 構(gòu)建一個正方形,餅狀圖是這個正方形的內(nèi)切圓 */ rectf=new RectF((int)(centreX-radius),(int)(centreY-radius),(int)(centreX+radius),(int)(centreY+radius)); /** * 設(shè)置餅狀圖畫筆的顏色,先繪制大球占的比例 */ 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點鐘轉(zhuǎn)換為起始角度為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); /** * 開始繪制文字,先設(shè)置文字顏色 */ textPaint.setColor(getResources().getColor(typedValue.resourceId)); /** * 設(shè)置問題大小 */ textPaint.setTextSize(textSize); /** * 大球數(shù)量 */ String strBig = strBigBallName + mBigBallNumber; /** * 測量文字寬度 */ float textBigWidth =textPaint.measureText(strBig); Paint.FontMetrics fontMetrics=textPaint.getFontMetrics(); /** * 繪制上邊大球數(shù)量 */ canvas.drawText(strBig, width * 9 / 20 + textBigWidth / 2, height *23/ 60 - fontMetrics.top / 3, textPaint); /** * 小球數(shù)量 */ String strSmall = strSmallBallName + mSmallBallNumber; /** * 測量文字寬度 */ float textUnderWidth=textPaint.measureText(strSmall); /** * 繪制下邊的小球數(shù)量 */ 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,四個參數(shù)分別是文字內(nèi)容,起始繪制x坐標(biāo),起始繪制y坐標(biāo),畫筆 * 以為設(shè)置了居中繪制,因此穿進去的xy坐標(biāo)為文字的中心點 */ 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對象,計算位置的坐標(biāo)。參考:使用FontMetrics對象計算位置坐標(biāo)
設(shè)置文字繪制以中心為起點開始繪制
textPaint.setTextAlign(Paint.Align.CENTER);
x的坐標(biāo)好計算,y坐標(biāo)需要按需使用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; /** * 大小球的數(shù)量 */ private int mBigBallNumber; private int mSmallBallNumber; /** * 大小球所占的百分比 */ private String mPercentBigBall; private String mPercentSmallBall; /** * 動態(tài)獲取屬性 */ 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) { /** * 設(shè)置餅狀圖畫筆 */ piePaint =new Paint(); piePaint.setAntiAlias(true); piePaint.setStyle(Paint.Style.FILL); /** * 設(shè)置文字畫筆 */ textPaint=new Paint(); textPaint.setStyle(Paint.Style.STROKE); textPaint.setAntiAlias(true); textPaint.setTextAlign(Paint.Align.CENTER); /** * 下邊設(shè)置一些默認的值,如果調(diào)用者沒有傳值進來的話,用這些默認值 */ 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坐標(biāo) */ float centreX= getWidth()/5; /** * 餅狀圖的y坐標(biāo) */ 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); /** * 構(gòu)建一個正方形,餅狀圖是這個正方形的內(nèi)切圓 */ rectf=new RectF((int)(centreX-radius),(int)(centreY-radius),(int)(centreX+radius),(int)(centreY+radius)); /** * 設(shè)置餅狀圖畫筆的顏色,先繪制大球占的比例 */ 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點鐘轉(zhuǎn)換為起始角度為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); /** * 開始繪制文字,先設(shè)置文字顏色 */ textPaint.setColor(getResources().getColor(typedValue.resourceId)); /** * 設(shè)置問題大小 */ textPaint.setTextSize(textSize); /** * 大球數(shù)量 */ String strBig = strBigBallName + mBigBallNumber; /** * 測量文字寬度 */ float textBigWidth =textPaint.measureText(strBig); Paint.FontMetrics fontMetrics=textPaint.getFontMetrics(); /** * 繪制上邊大球數(shù)量 */ canvas.drawText(strBig, width * 9 / 20 + textBigWidth / 2, height *23/ 60 - fontMetrics.top / 3, textPaint); /** * 小球數(shù)量 */ String strSmall = strSmallBallName + mSmallBallNumber; /** * 測量文字寬度 */ float textUnderWidth=textPaint.measureText(strSmall); /** * 繪制下邊的小球數(shù)量 */ 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,四個參數(shù)分別是文字內(nèi)容,起始繪制x坐標(biāo),起始繪制y坐標(biāo),畫筆 * 以為設(shè)置了居中繪制,因此穿進去的xy坐標(biāo)為文字的中心點 */ 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(); } }
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持創(chuàng)新互聯(lián)。
網(wǎng)頁題目:Android自定義控件實現(xiàn)餅狀圖
文章出自:http://muchs.cn/article44/igegee.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供標(biāo)簽優(yōu)化、網(wǎng)站設(shè)計公司、搜索引擎優(yōu)化、自適應(yīng)網(wǎng)站、外貿(mào)網(wǎng)站建設(shè)、企業(yè)網(wǎng)站制作
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)