android 自定義餅圖
阿新 • • 發佈:2018-12-31
本程式碼是一年前公司專案需要自己所寫,當時做android專案需要統計的功能,統計的圖表包括餅圖、柱狀圖、折線圖,程式碼寫的有些笨拙!希望大家能夠看懂!其程式碼做拋磚引玉,希望大家能夠再改寫下!可以用多執行緒做出動畫,是不是更好呢?這些後期我也沒有整理過,所以誰能再整理下!
CookieData.java
class CookieData
package com.wforyou.dhh.ui.widget; public class CookieData { /**名稱**/ private String name; /**數值**/ private double data; /**顏色**/ private int color; public String getName() { return name; } public void setName(String name) { this.name = name; } public double getData() { return data; } public void setData(double data) { this.data = data; } public int getColor() { return color; } public void setColor(int color) { this.color = color; } @Override public String toString() { return "CookieData [name=" + name + ", data=" + data + ", color=" + color + "]"; } }
Cookie.java
package com.wforyou.dhh.ui.widget; import com.wforyou.dhh.util.Logs; import android.content.Context; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.graphics.RectF; import android.graphics.Paint.Style; import android.util.AttributeSet; import android.util.DisplayMetrics; import android.util.Log; import android.view.View; import android.view.View.MeasureSpec; import android.widget.TextView; public class Cookie extends View { private int mAscent; private String mText = ""; // 螢幕的高度 public static int heightPixels = 0; // 螢幕的寬度 public static int widthPixels = 0; /** 畫筆 **/ private static Paint paint; /** 半徑 **/ private float radius = 130; /** X起點座標 **/ private static float xstartcoordinate = 100; /** Y起點座標 **/ private static float ystartcoordinate = 180; /** X終點座標 **/ private static float xendcoordinate = 400; /** Y終點座標 **/ private static float yendcoordinate = 180; private static RectF f; private static int[] colors = { Color.parseColor("#29A3A4"), Color.parseColor("#4239A2"), Color.parseColor("#9C46FF"), Color.parseColor("#E8C000"), Color.parseColor("#4B0064"), Color.parseColor("#16699B"), Color.parseColor("#3E635B"), Color.parseColor("#B19862"), Color.parseColor("#F736F7"), Color.parseColor("#164988") }; private String[] textValues = { "褲子", "裙子", "內褲", "文胸", "保暖衣" }; private double[] numberValues = { 63, 80, 0, 150, 140 }; private String noteText = ""; private static float statar = 0; private static float addx = 0; private static float addy = 0; // 距離螢幕左邊的距離 private static float marginleft = 0; // 距離螢幕上邊的距離 private static float margintop = 40; // 距離螢幕右邊的距離 private static float marginrigth = 0; // 距離螢幕下邊的距離 private static float margindown = 50; /** 圓下方提示 **/ private String downNoteText = "大類 金額"; public Cookie(Context context) { super(context); } public Cookie(Context context, AttributeSet attrs) { super(context, attrs); } public Cookie(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); } public String[] getTextValues() { return textValues; } public void setTextValues(String[] textValues) { this.textValues = textValues; } public double[] getNumberValues() { return numberValues; } public void setNumberValues(double[] numberValues) { this.numberValues = numberValues; } public String getNoteText() { return noteText; } public void setNoteText(String noteText) { this.noteText = noteText; } public String getDownNoteText() { return downNoteText; } public void setDownNoteText(String downNoteText) { this.downNoteText = downNoteText; } @Override protected void onDraw(Canvas canvas) { canvas.drawColor(Color.WHITE); getScreenData(); paint = new Paint(); canvas.drawText(mText, getPaddingLeft(), getPaddingTop() - mAscent, paint); // 抗鋸齒 paint.setAntiAlias(true); // 實心扇形 paint.setStyle(Style.FILL); // 設定矩形 getRectF(); // 得到總資料 double dsum = getSum(); getaddy(); int intlength = numberValues.length; float temp = 0; float dtemp = 0; for (int i = 0; i < intlength; i++) { if (numberValues[i] > 0) { doDrawTextNote(colors[i], textValues[i], 50, canvas); dodrawdegree(canvas, colors[i], temp, (float) (numberValues[i] / dsum) * 360);// 畫扇形 dtemp = temp + (float) (numberValues[i] / dsum) * 360 / 2; temp += ((float) (numberValues[i] / dsum) * 360); } } temp = 0; dtemp = 0; for (int i = 0; i < intlength; i++) { if (numberValues[i] > 0) { dtemp = temp + (float) (numberValues[i] / dsum) * 360 / 2; drawTextdegree(gettempCentalxy(dtemp)[0], gettempCentalxy(dtemp)[1], (float) (numberValues[i] / dsum) * 360, canvas); temp += ((float) (numberValues[i] / dsum) * 360); } } doDrawNote(canvas); paint.setTextSize(15); canvas.drawText(downNoteText, xstartcoordinate - paint.measureText(downNoteText) / 2, ystartcoordinate + radius + 25, paint); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { setMeasuredDimension(measureWidth(widthMeasureSpec), measureHeight(heightMeasureSpec)); } public void doDrawNote(Canvas canvas) { paint.setColor(Color.BLACK); paint.setTextSize(20); canvas.drawText(noteText, (widthPixels / 2 + marginleft - marginrigth) - paint.measureText(noteText) / 2, margintop + 30, paint); } public double getSum() { double tempRtn = 0; for (double temp : numberValues) { tempRtn += temp; } return tempRtn; } public void getRectF() { f = new RectF(); f.set(xstartcoordinate, ystartcoordinate, xendcoordinate, yendcoordinate); xstartcoordinate = (xstartcoordinate + xendcoordinate) / 2; ystartcoordinate = (ystartcoordinate + yendcoordinate) / 2; // radius=(xendcoordinate-xstartcoordinate)/2; } /** * 畫扇形 * * @param canvas * @param name * 顏色 * @param startAngle * 開始的度數 * @param sweepAngle * 畫多少度 */ public void dodrawdegree(Canvas canvas, int name, float startAngle, float sweepAngle) { paint.setColor(name); canvas.drawArc(f, startAngle, sweepAngle, true, paint); } public void drawTextdegree(float xtemp, float ytemp, float degree, Canvas canvas) { paint.setColor(Color.WHITE); paint.setTextSize(20); String strTemp = String.valueOf(Math.round((degree / 360) * 100))+ "%"; switch (getDirection(xtemp, ytemp)) { case 0: ytemp=ytemp+10f; break; case 1: xtemp=xtemp-paint.measureText(strTemp)/2; ytemp=ytemp+10f; break; case 2: xtemp=xtemp-paint.measureText(strTemp)/2; break; case 3: xtemp=xtemp-paint.measureText(strTemp)/2; ytemp=ytemp+10f; break; case 4: ytemp=ytemp-10f; xtemp=xtemp-paint.measureText(strTemp)/2; break; case 5: ytemp=ytemp+10f; xtemp=xtemp-paint.measureText(strTemp)/2; break; case 6: ytemp=ytemp+10f; xtemp=xtemp-paint.measureText(strTemp)/2; break; case 7: ytemp=ytemp+10f; xtemp=xtemp-paint.measureText(strTemp)/2; break; default: break; } canvas.drawText(strTemp , xtemp, ytemp, paint); } public float[] gettempCentalxy(float degree) { float[] fRtn = { 0.0f, 0.0f }; float xtemp, ytemp; // xtemp = (float) ((xstartcoordinate + xstartcoordinate + radius // * Math.cos(degree * (Math.PI / 180))) / 2); // ytemp = (float) ((ystartcoordinate + ystartcoordinate + radius // * Math.sin(degree * (Math.PI / 180))) / 2); xtemp = (float) ((xstartcoordinate + (radius-30) * Math.cos(degree * (Math.PI / 180)))); ytemp = (float) ((ystartcoordinate + (radius-30) * Math.sin(degree * (Math.PI / 180)))); fRtn[0] = xtemp; fRtn[1] = ytemp; return fRtn; } public void doDrawTextNote(int color, String text, double number, Canvas canvas) { paint.setTextSize(15); paint.setColor(color); canvas.drawRect((widthPixels / 4 * 3), addy + 15 + statar, (widthPixels / 4 * 3) + 15.0f, addy + 30 + statar, paint); paint.setColor(Color.BLACK); canvas.drawText(text, (widthPixels / 4 * 3) + 20.0f, addy + 28 + statar, paint); statar += 30.0f; Logs.v("msg", text); } public void getaddy() { int intlength = 0; for (double temp : numberValues) { if (temp > 0) { intlength++; } } statar = 0; Logs.v("msg", "data intlength = " + intlength); float temp; if (intlength == 1) { temp = 15f; } else { temp = (intlength - 1) * 15f + intlength * 15f; } addy = ystartcoordinate - temp / 2 - 15f; } private void getScreenData() { DisplayMetrics metrics = getResources().getDisplayMetrics(); // // 螢幕高 // heightPixels = metrics.heightPixels; // // 螢幕寬 // widthPixels = metrics.widthPixels; // 螢幕高 heightPixels = getHeight(); // 螢幕寬 widthPixels = getWidth(); marginleft = getPaddingLeft(); margindown = getPaddingBottom(); margintop = getPaddingTop(); marginrigth = getPaddingRight(); Logs.v("msg", "Cookie heightPixels =" + String.valueOf(heightPixels) + " widthPixels =" + String.valueOf(widthPixels)); // 設定x座標起點 xstartcoordinate = ((widthPixels / 8) * 3 + marginleft - marginrigth) - radius; // 設定x座標終點 xendcoordinate = ((widthPixels / 8) * 3 + marginleft - marginrigth) + radius; // 設定y座標起點 ystartcoordinate = (heightPixels / 2 + margintop - margindown) - radius; // 設定y座標終點 yendcoordinate = (heightPixels / 2 + margintop - margindown) + radius; } private int measureWidth(int measureSpec) { paint = new Paint(); int result = 0; int specMode = MeasureSpec.getMode(measureSpec); int specSize = MeasureSpec.getSize(measureSpec); if (specMode == MeasureSpec.EXACTLY) { // We were told how big to be result = specSize; } else { // Measure the text if (mText.equals("")) { DisplayMetrics metrics = getResources().getDisplayMetrics(); result = metrics.widthPixels / 2 + getPaddingLeft() + getPaddingRight(); } else { result = (int) paint.measureText(mText) + getPaddingLeft() + getPaddingRight(); } if (specMode == MeasureSpec.AT_MOST) { // Respect AT_MOST value if that was what is called for by // measureSpec result = Math.min(result, specSize); } } return result; } /** * Determines the height of this view * * @param measureSpec * A measureSpec packed into an int * @return The height of the view, honoring constraints from measureSpec */ private int measureHeight(int measureSpec) { paint = new Paint(); int result = 0; int specMode = MeasureSpec.getMode(measureSpec); int specSize = MeasureSpec.getSize(measureSpec); mAscent = (int) paint.ascent(); if (specMode == MeasureSpec.EXACTLY) { // We were told how big to be result = specSize; } else { if (mText.equals("")) { DisplayMetrics metrics = getResources().getDisplayMetrics(); result = (int) (metrics.heightPixels - 150 + getPaddingLeft() + getPaddingRight()); } else { result = (int) (-mAscent + paint.descent()) + getPaddingTop() + getPaddingBottom(); } if (specMode == MeasureSpec.AT_MOST) { result = Math.min(result, specSize); } } return result; } public int getDirection(float xtemp, float ytemp) { if (xstartcoordinate < xtemp && ystartcoordinate < ytemp) { Log.v("msg", "msg = rightdrown"); return 7; } if (xstartcoordinate > xtemp && ystartcoordinate > ytemp) { Log.v("msg", "msg = lefttop"); return 3; } if (xstartcoordinate > xtemp && ystartcoordinate < ytemp) { Log.v("msg", "msg = leftdrown"); return 5; } if (xstartcoordinate < xtemp && ystartcoordinate > ytemp) { Log.v("msg", "msg = rigthtop"); return 1; } if (xstartcoordinate < xtemp && ystartcoordinate == ytemp) { Log.v("msg", "msg = Drown"); return 6; } if (xstartcoordinate == xtemp && ystartcoordinate < ytemp) { Log.v("msg", "msg = rigth"); return 0; } if (xstartcoordinate == xtemp && ystartcoordinate > ytemp) { Log.v("msg", "msg = top"); return 2; } if (xstartcoordinate > xtemp && ystartcoordinate == ytemp) { Log.v("msg", "msg = left"); return 4; } return 0; } }
不能把全部程式碼粘貼出來望諒解!涉及到公司的利益
用法
/**波段金額比例**/
private Cookie mCkAddBangAmount;
/**波段數量比例**/
private Cookie mCkAddBangQuantity;
/**大類金額比例**/
private Cookie mCkAddTypeAmount;
/**大類數量比例**/
private Cookie mCkAddTypeQuantity;
/**預期和實際對比**/
private LineHistogram mHgAddContrast;
方法操作
public void getAddCookieToBangAmount(){ SqlStatistics service = new SqlStatistics(getActivity()); DHHApp.setUserId("J0049"); ArrayList<OrderStatistics> arrayList = service.getSumAmountForBang(true); Logs.v("msg", "test data = " + arrayList.toString()); String[] datatext = new String[arrayList.size()]; double[] thinkdata = new double[arrayList.size()]; int intcount = 0; for (OrderStatistics orderStatistics : arrayList) { datatext[intcount] = orderStatistics.getShowName(); thinkdata[intcount]=orderStatistics.getShowNumber(); intcount++; } mCkAddBangAmount.setTextValues(datatext); mCkAddBangAmount.setNumberValues(thinkdata); mCkAddBangAmount.setDownNoteText("波段 金額"); } public void getAddCookieToBangQuantity(){ SqlStatistics service = new SqlStatistics(getActivity()); DHHApp.setUserId("J0049"); ArrayList<OrderStatistics> arrayList = service.getSumAmountForBang(true); Logs.v("msg", "test data = " + arrayList.toString()); String[] datatext = new String[arrayList.size()]; double[] thinkdata = new double[arrayList.size()]; int intcount = 0; for (OrderStatistics orderStatistics : arrayList) { datatext[intcount] = orderStatistics.getShowName(); thinkdata[intcount]=orderStatistics.getShowNumber(); intcount++; } mCkAddBangQuantity.setTextValues(datatext); mCkAddBangQuantity.setNumberValues(thinkdata); mCkAddBangQuantity.setDownNoteText("波段 數量"); }
檔案佈局
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal" >
<com.wforyou.dhh.ui.widget.Cookie
android:id="@+id/user_cookie_bangAmount"
android:layout_width="wrap_content"
android:layout_height="fill_parent" />
<com.wforyou.dhh.ui.widget.Cookie
android:id="@+id/user_cookie_bangQuantity"
android:layout_width="wrap_content"
android:layout_toRightOf="@+id/user_cookie_bangAmount"
android:layout_height="fill_parent" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:layout_marginLeft="35dp"
android:layout_marginTop="20dp"
android:background="@drawable/bg_tb_left"
android:paddingLeft="60dp" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_marginTop="20dp"
android:background="@drawable/bg_user_bangcontrast" />
</RelativeLayout>