android自定義柱狀圖
阿新 • • 發佈:2019-01-07
本程式碼是一年前公司專案需要自己所寫,當時做android專案需要統計的功能,統計的圖表包括餅圖、柱狀圖、折線圖,程式碼寫的有些笨拙!希望大家能夠看懂!其程式碼做拋磚引玉,希望大家能夠再改寫下!可以用多執行緒做出動畫,是不是更好呢?這些後期我也沒有整理過,所以誰能再整理下!
SingleHistorgram.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.util.AttributeSet; import android.util.DisplayMetrics; import android.util.Log; import android.view.View; import android.view.View.MeasureSpec; public class SingleHistorgram extends View { private int mAscent; private String mText = ""; // 螢幕的高度 public static int heightPixels = 0; // 螢幕的寬度 public static int widthPixels = 0; // X軸 public static float XLength = 600.f; // Y軸 public static float Ylength = 300.0f; // X軸最大值 public static float XMAXLENGTH = 2500.0f; // Y軸最大值 public static float YMAXLENGTH = 250.0f; // 畫筆 private static Paint paint; // 距離螢幕左邊的距離 private static float marginleft = 40; // 距離螢幕上邊的距離 private static float margintop = 60; // 統計圖的標題 public static String strText = "計劃達成"; // 實際提示資訊 public String noteText = "提示"; // 計劃提示資訊 public static String noteText2 = "實際訂購金額"; // 平均刻度值 public static int average = 40; // y軸刻度的平均值,需要幾個刻度 public static int yaverage = 6; // 以多少畫素取幾個刻度 public static float faverage = 40; // x軸刻度的間距 public static float xaverage = 40; /** 文字資訊 **/ private String[] textValues = { "褲子", "文胸", "T恤", "襯衣", "保暖衣", "保暖褲", "頭巾", "圍巾" }; /** 文字對應的值 **/ private double[] numberValues = { 300, 180, 150, 180, 900, 35, 255, 125 }; /** 柱狀圖的顏色 **/ public static int valuescolors = Color.parseColor("#C96118"); /** 平均刻度值與實際刻度值的比 **/ public static float xpaverage = 1; /** Y軸提示資訊 **/ public String yNoteText = "金額"; /** X軸提示資訊 **/ public static String xText = ""; /** 文字資訊的間距 **/ public static float yspace = 80; /**柱狀的寬度**/ private static float historgramspace=20; 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 getyNoteText() { return yNoteText; } public void setyNoteText(String yNoteText) { this.yNoteText = yNoteText; } public SingleHistorgram(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); // TODO Auto-generated constructor stub } public SingleHistorgram(Context context, AttributeSet attrs) { super(context, attrs); // TODO Auto-generated constructor stub } public SingleHistorgram(Context context) { super(context); // TODO Auto-generated constructor stub } @Override protected void onDraw(Canvas canvas) { getWidthHeigth(); getmaxyLength(); canvas.drawColor(Color.WHITE); paint = new Paint(); paint.setAntiAlias(true); DrawXY(canvas); drawCentreNote(canvas); getyaverage(); getAverage(XMAXLENGTH); getxpaverage(); DrawYText(canvas); DrawXText(canvas); drawtrue(canvas); } private void getWidthHeigth() { // DisplayMetrics metrics = getResources().getDisplayMetrics(); // // // 螢幕高 // heightPixels = metrics.heightPixels; // // 螢幕寬 // widthPixels = metrics.widthPixels; // 螢幕高 heightPixels = getHeight(); // 螢幕寬 widthPixels = getWidth(); marginleft = getPaddingLeft() + 50f; margintop = getPaddingTop(); // X軸 XLength = widthPixels; // Y軸 Ylength = heightPixels - 70; } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { setMeasuredDimension(measureWidth(widthMeasureSpec), measureHeight(heightMeasureSpec)); } public void getmaxyLength() { double temp = numberValues[0]; for (int i = 1; i < numberValues.length; i++) { if (temp < numberValues[i]) { temp = numberValues[i]; } } XMAXLENGTH = (float) temp; } public void DrawXY(Canvas canvas) { paint.setColor(Color.BLACK); canvas.drawLine(marginleft, margintop, marginleft, Ylength, paint); canvas.drawLine(marginleft, Ylength, XLength, Ylength, paint); } public void getyaverage() { yaverage = (int) ((Ylength - margintop - 10) % faverage == 0.0 ? (Ylength - margintop - 10) / faverage : (Ylength - margintop - 10) / faverage); } public String getAverage(double d) { String strRtn = "0"; int intnum = (int) (d / yaverage); int inttemp = Integer .valueOf(getNumber(String.valueOf(intnum).length())); if (inttemp == 1) { strRtn = String .valueOf((int) (d % yaverage) == 0 ? ((int) (d / yaverage)) : ((int) (d / yaverage) + 1)); } else { strRtn = String.valueOf(intnum % inttemp == 0 ? (intnum / inttemp) * inttemp : (intnum / inttemp + 1) * inttemp); } average = Integer.valueOf(strRtn); Log.v("msg", "average = " + String.valueOf(average) + " YMAXLENGTH = " + String.valueOf(YMAXLENGTH)); return strRtn; } public void getxpaverage() { xpaverage = average / faverage; Log.v("msg", "xp =" + String.valueOf(xpaverage)); } public String getNumber(int num) { String strRtn = "1"; if (num > 0) { for (int i = 0; i < num - 1; i++) { strRtn += "0"; } } return strRtn; } public void DrawYText(Canvas canvas) { paint.setColor(Color.BLACK); Float temp = 0.0f; paint.setTextSize(12); for (int i = 1; i < yaverage + 1; i++) { paint.setColor(Color.BLACK); temp = Ylength - Float.valueOf(faverage * i); Log.v("msg", String.valueOf(temp)); // canvas.drawLine(marginleft - 10, temp, marginleft, temp, paint); canvas.drawText( String.valueOf(Integer.valueOf(average) * i), marginleft - paint.measureText(String.valueOf(Integer .valueOf(average) * i)) - 5f, temp + 4.5f, paint); paint.setColor(Color.parseColor("#9EADD1")); canvas.drawLine(marginleft, temp, XLength, temp, paint); } paint.setColor(Color.BLACK); // canvas.drawLine(marginleft, margintop, marginleft, margintop-70, // paint); paint.setTextSize(15); canvas.drawText(yNoteText, marginleft - paint.measureText(yNoteText) - 5f, Ylength - 15, paint); canvas.drawText(xText, marginleft, Ylength + 40, paint); } public void DrawXText(Canvas canvas) { paint.setColor(Color.BLACK); float temp = marginleft - 20f; for (int i = 0; i < textValues.length; i++) { temp += yspace; canvas.drawLine(temp, Ylength, temp, Ylength + 5f, paint); canvas.drawText(textValues[i], temp - (paint.measureText(textValues[i]) / 2), Ylength + 20f, paint); } } public void drawtrue(Canvas canvas) { float temp = marginleft - 20; paint.setColor(valuescolors); if(historgramspace>=yspace){ historgramspace=yspace/2-10; } for (int i = 0; i < numberValues.length; i++) { temp += yspace; canvas.drawRect(temp - historgramspace, Ylength - (float) (numberValues[i] / xpaverage), temp + historgramspace, Ylength, paint); } paint.setColor(Color.BLACK); temp = marginleft - 20; for (int i = 0; i < numberValues.length; i++) { temp += yspace; canvas.drawText( String.valueOf(numberValues[i]), temp - (paint.measureText(String .valueOf(numberValues[i])) / 2), Ylength - 20.0f, paint); } } /** * 提示資訊畫中心 * * @param canvas */ public void drawCentreNote(Canvas canvas) { float temp = XLength / 2;// 得到螢幕中間的畫素值 paint.setColor(valuescolors);// 設定顏色 paint.setTextSize(15);// 設定字型 canvas.drawRect(temp - 10, Ylength + 35, temp + 10, Ylength + 55, paint); paint.setColor(Color.BLACK); // 畫提示資訊 canvas.drawText(noteText, temp + 30, Ylength + 50f, paint); canvas.drawText("0", marginleft - 10f, Ylength + 10, paint); } 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("")) { int temp= (int) getAcquiesceWhidth(); result = temp<750?750:temp + 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 { // Measure the text (beware: ascent is a negative number) 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 float getAcquiesceWhidth() { float rtn = 100; if (numberValues.length > 0) { rtn = getPaddingLeft() + 40 + (yspace * (numberValues.length + 1)); } return rtn; } }
用法
/** 數量選擇按鈕 **/ private RadioButton mRbtAmount; /** 金額選擇按鈕 **/ private RadioButton mRbtQuantity; /** 柱狀圖選擇按鈕 **/ private RadioButton mRbtHistorgram; /** 餅圖選擇按鈕 **/ private RadioButton mRbtPie; /** 製作圖表按鈕 **/ private ImageView mLvMake; /** 預設選擇柱狀圖 **/ private boolean ishistorgram = true; /** 預設選擇金額 **/ private boolean isamount = true; /** 選擇的文字 **/ private String mattribute = ""; /** 下拉框介面卡 **/ private DropDownSpinerAdapter mUserAdapter; private List<String> mUserList = new ArrayList<String>(); private List<tab_AttributeDefinition> mAttrList = new ArrayList<tab_AttributeDefinition>(); private String[] notetext = { "大類", "顏色", "適合人群", "年份", "系列" }; /** 資料 **/ private ArrayList<OrderStatistics> mAlistOrderStatistics; /** 資料文字顯示資訊 **/ private String[] mStrDataText; /** 資料引數 **/ private double[] mDbThinkData; /** 餅圖 **/ private Cookie mCookie; /** 柱狀圖 **/ private SingleHistorgram mHistorgram; /** 預設顯示 **/ private ImageView mIwNoteInfo; /** 新增柱狀圖的容器 **/ private LinearLayout mLtAddHistorgram; /** 新增餅圖的容器 **/ private LinearLayout mLtAddCookie; private HorizontalScrollView mScrollView; /** 柱狀圖提示資訊 **/ private String mStrAttrinuteName;
private OnClickListener mLvMakeClickListener = new OnClickListener() { @Override public void onClick(View v) { Logs.v("msg", "data is test make pei"); getNumber(); if (mAlistOrderStatistics.size() > 0) { if (ishistorgram) { if (mLtAddHistorgram.getChildCount() > 0) { mLtAddHistorgram.removeAllViews(); } mHistorgram = new SingleHistorgram(getActivity()); mHistorgram.setTextValues(mStrDataText); mHistorgram.setNumberValues(mDbThinkData); mHistorgram.setNoteText(mStrAttrinuteName); if (isamount) { mHistorgram.setyNoteText("金額"); } else { mHistorgram.setyNoteText("數量"); } mLtAddHistorgram.addView(mHistorgram); mIwNoteInfo.setVisibility(View.GONE); mLtAddCookie.setVisibility(View.GONE); mScrollView.setVisibility(View.VISIBLE); } else { mCookie = new Cookie(getActivity()); mCookie.setTextValues(mStrDataText); mCookie.setNumberValues(mDbThinkData); mCookie.setNoteText(""); if (isamount) { mCookie.setDownNoteText("金額"); } else { mCookie.setDownNoteText("數量"); } mCookie.setLayoutParams(new android.widget.LinearLayout.LayoutParams( LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT)); if (mLtAddCookie.getChildCount() > 0) { mLtAddCookie.removeAllViews(); } mLtAddCookie.addView(mCookie); mIwNoteInfo.setVisibility(View.GONE); mLtAddCookie.setVisibility(View.VISIBLE); mScrollView.setVisibility(View.GONE); } } else { // mIwNoteInfo.setVisibility(View.VISIBLE); // mCookie.setVisibility(View.GONE); // mScrollView.setVisibility(View.GONE); } } };
佈局
<HorizontalScrollView
android:id="@+id/user_hsv_SingleHistorgram"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<LinearLayout
android:id="@+id/user_add_SingleHistorgram"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
android:paddingLeft="20dp"
android:paddingTop="20dp" >
</LinearLayout>
</HorizontalScrollView>