編輯:關於Android編程
本文實例講述了Android編程實現canvas繪制餅狀統計圖功能。分享給大家供大家參考,具體如下:
本例的目的是實現一個簡單的餅狀統計圖,效果如下:
特點:
1.使用非常方便,可放在xml布局文件中,然後在代碼中設置內容,即:
PieChartView pieChartView = (PieChartView) findViewById(R.id.pie_chart); PieChartView.PieItemBean[] items = new PieChartView.PieItemBean[]{ new PieChartView.PieItemBean("娛樂", 200), new PieChartView.PieItemBean("旅行", 100), new PieChartView.PieItemBean("學習", 120), new PieChartView.PieItemBean("人際關系", 160), new PieChartView.PieItemBean("交通", 100), new PieChartView.PieItemBean("餐飲", 480) }; pieChartView.setPieItems(items);
2.條目數量,大小及折線位置,長度均自適應。左側條目往左側劃線,右側條目往右側劃線,文字描述與百分比居中對齊,並且文字“下劃線”與文字長度自適應。對於很小的條目,將自動將折線延長以盡可能避免文字遮蓋
核心代碼:PieChartView.Java:
public class PieChartView extends View { private int screenW, screenH; /** * The paint to draw text, pie and line. */ private Paint textPaint, piePaint, linePaint; /** * The center and the radius of the pie. */ private int pieCenterX, pieCenterY, pieRadius; /** * The oval to draw the oval in. */ private RectF pieOval; private float smallMargin; private int[] mPieColors = new int[]{Color.RED, Color.GREEN, Color.BLUE, Color.YELLOW, Color.MAGENTA, Color.CYAN}; private PieItemBean[] mPieItems; private float totalValue; public PieChartView(Context context) { super(context); init(context); } public PieChartView(Context context, AttributeSet attrs) { super(context, attrs); init(context); } public PieChartView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); init(context); } private void init(Context context) { //init screen screenW = ScreenUtils.getScreenW(context); screenH = ScreenUtils.getScreenH(context); pieCenterX = screenW / 2; pieCenterY = screenH / 3; pieRadius = screenW / 4; smallMargin = ScreenUtils.dp2px(context, 5); pieOval = new RectF(); pieOval.left = pieCenterX - pieRadius; pieOval.top = pieCenterY - pieRadius; pieOval.right = pieCenterX + pieRadius; pieOval.bottom = pieCenterY + pieRadius; //The paint to draw text. textPaint = new Paint(); textPaint.setAntiAlias(true); textPaint.setTextSize(ScreenUtils.dp2px(context, 16)); //The paint to draw circle. piePaint = new Paint(); piePaint.setAntiAlias(true); piePaint.setStyle(Paint.Style.FILL); //The paint to draw line to show the concrete text linePaint = new Paint(); linePaint.setAntiAlias(true); linePaint.setStrokeWidth(ScreenUtils.dp2px(context, 1)); } //The degree position of the last item arc's center. private float lastDegree = 0; //The count of the continues 'small' item. private int addTimes = 0; @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); if (mPieItems != null && mPieItems.length > 0) { float start = 0.0f; for (int i = 0; i < mPieItems.length; i++) { //draw pie piePaint.setColor(mPieColors[i % mPieColors.length]); float sweep = mPieItems[i].getItemValue() / totalValue * 360; canvas.drawArc(pieOval, start, sweep, true, piePaint); //draw line away from the pie float radians = (float) ((start + sweep / 2) / 180 * Math.PI); float lineStartX = pieCenterX + pieRadius * 0.7f * (float) (Math.cos(radians)); float lineStartY = pieCenterY + pieRadius * 0.7f * (float) (Math.sin(radians)); float lineStopX, lineStopY; float rate; if (getOffset(start + sweep / 2) > 60) { rate = 1.3f; } else if (getOffset(start + sweep / 2) > 30) { rate = 1.2f; } else { rate = 1.1f; } //If the item is very small, make the text further away from the pie to avoid being hided by other text. if (start + sweep / 2 - lastDegree < 30) { addTimes++; rate += 0.2f * addTimes; } else { addTimes = 0; } lineStopX = pieCenterX + pieRadius * rate * (float) (Math.cos(radians)); lineStopY = pieCenterY + pieRadius * rate * (float) (Math.sin(radians)); canvas.drawLine(lineStartX, lineStartY, lineStopX, lineStopY, linePaint); //write text String itemTypeText = mPieItems[i].getItemType(); String itemPercentText = Utility.formatFloat(mPieItems[i].getItemValue() / totalValue * 100) + "%"; float itemTypeTextLen = textPaint.measureText(itemTypeText); float itemPercentTextLen = textPaint.measureText(itemPercentText); float lineTextWidth = Math.max(itemTypeTextLen, itemPercentTextLen); float textStartX = lineStopX; float textStartY = lineStopY - smallMargin; float percentStartX = lineStopX; float percentStartY = lineStopY + textPaint.getTextSize(); if (lineStartX > pieCenterX) { textStartX += (smallMargin + Math.abs(itemTypeTextLen - lineTextWidth) / 2); percentStartX += (smallMargin + Math.abs(itemPercentTextLen - lineTextWidth) / 2); } else { textStartX -= (smallMargin + lineTextWidth - Math.abs(itemTypeTextLen - lineTextWidth) / 2); percentStartX -= (smallMargin + lineTextWidth - Math.abs(itemPercentTextLen - lineTextWidth) / 2); } canvas.drawText(itemTypeText, textStartX, textStartY, textPaint); //draw percent text canvas.drawText(itemPercentText, percentStartX, percentStartY, textPaint); //draw text underline float textLineStopX = lineStopX; if (lineStartX > pieCenterX) { textLineStopX += (lineTextWidth + smallMargin * 2); } else { textLineStopX -= (lineTextWidth + smallMargin * 2); } canvas.drawLine(lineStopX, lineStopY, textLineStopX, lineStopY, linePaint); lastDegree = start + sweep / 2; start += sweep; } } } public PieItemBean[] getPieItems() { return mPieItems; } public void setPieItems(PieItemBean[] pieItems) { this.mPieItems = pieItems; totalValue = 0; for (PieItemBean item : mPieItems) { totalValue += item.getItemValue(); } invalidate(); } private float getOffset(float radius) { int a = (int) (radius % 360 / 90); switch (a) { case 0: return radius; case 1: return 180 - radius; case 2: return radius - 180; case 3: return 360 - radius; } return radius; } static class PieItemBean { private String itemType; private float itemValue; PieItemBean(String itemType, float itemValue) { this.itemType = itemType; this.itemValue = itemValue; } public String getItemType() { return itemType; } public void setItemType(String itemType) { this.itemType = itemType; } public float getItemValue() { return itemValue; } public void setItemValue(float itemValue) { this.itemValue = itemValue; } } }
完整實例代碼點擊此處本站下載。
更多關於Android相關內容感興趣的讀者可查看本站專題:《Android圖形與圖像處理技巧總結》、《Android開發入門與進階教程》、《Android調試技巧與常見問題解決方法匯總》、《Android基本組件用法總結》、《Android視圖View技巧總結》、《Android布局layout技巧總結》及《Android控件用法總結》
希望本文所述對大家Android程序設計有所幫助。
先看看效果圖:源碼下載:自定義搜索功能代碼:SearchActivity.javapackage com.bzu.gxs.search.activity;import a
Android Scroll詳解(一):基礎知識 在前邊的文章中,我們已經對Android觸摸事件處理有了大致的了解,並且詳細探討了MotionEvent
自動完成文本框(AutoCompleteTextView)java.lang.Object;android.view.View;android.view.TextView
在一些電子商務網站上經常能夠看到一些滾動的廣告條,許多軟件在首次使用時也有類似的廣告條,如圖:其實在github上有實現這種效果的控件,不過這東西做起來也是很簡單,我們今