別廢話,先看圖
柱狀圖
這是一個統(tǒng)計控件舌菜。有點像progressbar。
在老菜鳥還小的時候亦镶,看到自定義的東西就抖日月。歲月流逝,小菜鳥依然堅定不移的暗戀著凍齡的志玲妹妹缤骨,可是皺紋已經(jīng)爬滿的菜鳥的丑臉“В現(xiàn)在老菜鳥看到自定義的東西就想擼一擼,雖然手法很搓绊起,技巧很low精拟。
- 首先分析控件。依然是從自定義控件三部曲之onMeasure開始,一組數(shù)據(jù)中蜂绎,match_parent的width是最大的那個數(shù)據(jù)栅表。比如總經(jīng)濟{ 4000,3000,2000 },那么4000的width是控件的match_parent师枣,3000就是最大width的3/4谨读。so,width不能onMeasure里計算了坛吁。要根據(jù)服務(wù)器給的數(shù)據(jù)來劳殖。
- onDraw,我們把經(jīng)濟對應(yīng)的節(jié)段可以看作是一個長方形拨脉,可以用drawRect方法哆姻。
開擼
根據(jù)上面分析,首先要算出來最大的總經(jīng)濟玫膀,也就是4000矛缨,然后傳進去每條數(shù)據(jù)。然后根據(jù)數(shù)據(jù)繪制出來帖旨。
- 初始化設(shè)置顏色
- 數(shù)據(jù)處理箕昭,按百分比處理每一段的數(shù)據(jù)。
public void setData(float death, float buy, float buiding, float kill, float hero, float other, final float max) {
rateList.clear();
final float total = death + buy + buiding + kill + hero + other;
rateList.add((float) death / total);
rateList.add((float) buy / total);
rateList.add((float) buiding / total);
rateList.add((float) kill / total);
rateList.add((float) hero / total);
rateList.add((float) other / total);
invalidate();
}
- 然后繪制解阅,第一段的起點是0,終點是長度货抄,然后每一段的起點都是前一段的終點述召。
start = 0;
progress = 0;
for (int i = 0; i < rateList.size() && i < colorList.size(); i++) {
float data = rateList.get(i);
mEnd = (int) ((progress + data) * mWidth);
if (mEnd > width) {
mEnd = mWidth;
}
mPaint.setColor(colorList.get(i));
canvas.drawRect(start, 0, mEnd, mHeight, mPaint);
progress = progress + data;
start = mEnd;
}
這樣繪制的控件長度是一樣的蟹地。即使一個經(jīng)濟是4000,一個是2000怪与,長度都一樣,不符合我們的要求分别。所以需要設(shè)置LayoutParams
private void setLayout(ProgressView pv, int i, float max) {
Resources resources = this.getResources();
DisplayMetrics displayMetrics = resources.getDisplayMetrics();
int widthPixels = displayMetrics.widthPixels;
ViewGroup.LayoutParams params = pv.getLayoutParams();
params.width = (int) (widthPixels * ((float) i / max));
pv.setLayoutParams(params);
}
這樣寫的控件一點都不靈活遍愿,如果是有5段數(shù)據(jù)茎杂,或者7段,我們就要修改源碼煌往。所以繼續(xù)優(yōu)化倾哺,優(yōu)化后的代碼就不給了轧邪。。羞海。
傳送門