Android鬼点子 100行代码,搞定柱状图!
最近,項(xiàng)目中遇到一個(gè)地方,要用到柱狀圖。所以這篇文章主要講怎么搞一個(gè)柱子。 100行代碼,搞定柱狀圖!
我的印象中柱子是這樣的。
恩,簡單,一個(gè)View直接放到xml,搞定! 但,設(shè)計(jì)師給的柱子是這樣的:
圓角,頭頂帶數(shù)字。恩,這樣用drawable也可以搞定。 但是,這個(gè)柱子是有一個(gè)動(dòng)畫的,就是進(jìn)入到界面的時(shí)候柱子不斷的長高。 這樣的話,綜合考慮還是用自定義View來做比較簡便。下面講一下思路。首先忽略動(dòng)畫,先把靜態(tài)的效果做出來。
關(guān)于尺寸
控件尺寸直接來自xml中的設(shè)置,無需進(jìn)行onMeasure測(cè)量。所以使用getWidth和getHeight獲取高度。
關(guān)于數(shù)據(jù)范圍
數(shù)據(jù)如果是一個(gè)柱子單獨(dú)顯示,則數(shù)據(jù)的范圍不是很重要,但是柱狀圖通常是由很多柱子并列顯示的,而這些柱子的單位高度都應(yīng)該是一樣的,所以提供設(shè)置最大值的范圍,最小值就是0.
關(guān)于數(shù)字的文字大小
由于柱子的寬度就是整個(gè)View的寬度,所以數(shù)字的寬度不能超過柱子的寬度。因?yàn)檫@個(gè)原因,文字的size需要?jiǎng)討B(tài)計(jì)算。意思就是 0和100000這兩個(gè)數(shù)字顯示的時(shí)候,文字的大小是不一樣的。
關(guān)于邊界值
0,是一個(gè)邊界值(最小值),當(dāng)顯示0的時(shí)候,并不是柱子不顯示的,而是顯示一個(gè)最小高度的。
關(guān)于動(dòng)畫
不停的設(shè)置值,就會(huì)形成動(dòng)畫。意思是先設(shè)置數(shù)據(jù)1,然后緊接著設(shè)數(shù)據(jù)2.3.4.5……一直到最終的顯示值,就會(huì)有動(dòng)畫效果。但是如果最終數(shù)值很大,1,1,1的增加就會(huì)很慢,動(dòng)畫時(shí)間很長。
代碼如下:
public class PPColumn extends View {int MAX = 100;//最大int corner = 40;int data = 0;//顯示的數(shù)int tempData = 0;int textPadding = 20;Paint mPaint;int mColor;Context mContext;public PPColumn(Context context) {super(context);mContext = context;}public PPColumn(Context context, @Nullable AttributeSet attrs) {super(context, attrs);mContext = context;initPaint();}public PPColumn(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {super(context, attrs, defStyleAttr);mContext = context;initPaint();}private void initPaint() {mPaint = new Paint();mPaint.setAntiAlias(true);mColor = mContext.getResources().getColor(R.color.colorPrimary);mPaint.setColor(mColor);}public void draw(Canvas canvas) {super.draw(canvas);if(data == 0){mPaint.setTextSize(getWidth() / 2);RectF oval3 = new RectF(0, getHeight() - DPUnitUtil.px2dip(mContext,20), getWidth(), getHeight());// 設(shè)置個(gè)新的長方形canvas.drawRoundRect(oval3, DPUnitUtil.px2dip(mContext,corner), DPUnitUtil.px2dip(mContext,corner), mPaint);canvas.drawText("0",getWidth() * 0.5f - mPaint.measureText("0") * 0.5f ,getHeight() - DPUnitUtil.px2dip(mContext,20) - 2 * DPUnitUtil.px2dip(mContext,textPadding),mPaint);return;}//防止數(shù)值很大的的時(shí)候,動(dòng)畫時(shí)間過長int step = data /100 + 1;if(tempData < data - step){tempData = tempData + step;}else{tempData = data;}//畫圓角矩形String S = tempData + "";//一個(gè)字和兩,三個(gè)字的字號(hào)相同if(S.length()<4){mPaint.setTextSize(getWidth() / 2);}else{mPaint.setTextSize(getWidth() / (S.length()-1));}float textH = mPaint.ascent() + mPaint.descent();float MaxH = getHeight() - textH - 2 * DPUnitUtil.px2dip(mContext,textPadding);//圓角矩形的實(shí)際高度float realH = MaxH / MAX * tempData;RectF oval3 = new RectF(0, getHeight() - realH, getWidth(), getHeight());// 設(shè)置個(gè)新的長方形canvas.drawRoundRect(oval3, DPUnitUtil.px2dip(mContext,corner), DPUnitUtil.px2dip(mContext,corner), mPaint);//寫數(shù)字canvas.drawText(S,getWidth() * 0.5f - mPaint.measureText(S) * 0.5f ,getHeight() - realH - 2 * DPUnitUtil.px2dip(mContext,textPadding),mPaint);if(tempData != data){postInvalidate();}}public void setData(int data, int MAX){this.data = data;tempData = 0;this.MAX = MAX;postInvalidate();}}復(fù)制代碼我是在xml中這樣使用的,也就是上面效果的樣子。
<LinearLayoutandroid:layout_width="match_parent"android:layout_height="0dp"android:layout_weight="1"><Viewandroid:layout_width="0dp"android:layout_height="match_parent"android:layout_weight="0.2" /><com.allrun.arsmartelevatorformanager.widget.PPColumnandroid:id="@+id/weihu_column"android:layout_width="0dp"android:layout_height="match_parent"android:layout_weight="1" /><Viewandroid:layout_width="0dp"android:layout_height="match_parent"android:layout_weight="2.4" /><com.allrun.arsmartelevatorformanager.widget.PPColumnandroid:id="@+id/weixiu_column"android:layout_width="0dp"android:layout_height="match_parent"android:layout_weight="1" /><Viewandroid:layout_width="0dp"android:layout_height="match_parent"android:layout_weight="2.4" /><com.allrun.arsmartelevatorformanager.widget.PPColumnandroid:id="@+id/jiuyuan_column"android:layout_width="0dp"android:layout_height="match_parent"android:layout_weight="1" /><Viewandroid:layout_width="0dp"android:layout_height="match_parent"android:layout_weight="0.2" /></LinearLayout> 復(fù)制代碼使用,設(shè)置值。Max最后要加1,防止0.幾的時(shí)候計(jì)算錯(cuò)誤。
int max = (int) (Math.max(Math.max(weihu, weixiu), jiuyuan) * 1.2) + 1; weihuColumn.setData(weihu, max); 復(fù)制代碼最后效果圖
總結(jié)
以上是生活随笔為你收集整理的Android鬼点子 100行代码,搞定柱状图!的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【MySQL】 已经存在大量数据的表做分
- 下一篇: [Android]Space控件的应用场