編輯:關於android開發
拿到美工效果圖,咱們程序員就得畫得一模一樣。 為了不被老板噴,只能多練啊。
聽說你覺得前面幾篇都so easy,那今天就帶你做個相對比較復雜的。
今天的效果圖如下(左邊是ui圖 右邊是實現圖):
自我感覺總體效果還不錯,至少大概畫得一樣了。上一個動態圖:
其實這個效果實現起來也不是很難,就是計算坐標,弧度之類的可能會比較麻煩,這裡分享寫這個其中一張手稿,請無視掉很丑的字,其實做自定義view 還是要在紙上多畫。所以希望大家也能這麼畫畫,思路會很順。
好的了,廢話不多說,快開始。
首先自定義屬性 構造函數,測量什麼的 你肯定已經很熟練 直接貼代碼了,注釋寫的很清楚
public class PanelView extends View { private int mWidth; private int mHeight; private int mPercent; //刻度寬度 private float mTikeWidth; //第二個弧的寬度 private int mScendArcWidth; //最小圓的半徑 private int mMinCircleRadius; //文字矩形的寬 private int mRectWidth; //文字矩形的高 private int mRectHeight; //文字內容 private String mText = ""; //文字的大小 private int mTextSize; //設置文字顏色 private int mTextColor; private int mArcColor; //小圓和指針顏色 private int mMinCircleColor; //刻度的個數 private int mTikeCount; private Context mContext; public PanelView(Context context) { this(context, null); } public PanelView(Context context, AttributeSet attrs) { this(context, attrs, 0); } public PanelView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); mContext = context; TypedArray a = context.obtainStyledAttributes(attrs,R.styleable.PanelView,defStyleAttr,0); mArcColor = a.getColor(R.styleable.PanelView_arcColor, Color.parseColor("#5FB1ED")); mMinCircleColor = a.getColor(R.styleable.PanelView_pointerColor,Color.parseColor("#C9DEEE")); mTikeCount = a.getInt(R.styleable.PanelView_tikeCount,12); mTextSize = a.getDimensionPixelSize(PxUtils.spToPx(R.styleable.PanelView_android_textSize,mContext),24); mText = a.getString(R.styleable.PanelView_android_text); mScendArcWidth = 50; } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { int widthSize = MeasureSpec.getSize(widthMeasureSpec); int widthMode = MeasureSpec.getMode(widthMeasureSpec); int heightSize = MeasureSpec.getSize(heightMeasureSpec); int heightMode = MeasureSpec.getMode(heightMeasureSpec); if (widthMode == MeasureSpec.EXACTLY) { mWidth = widthSize; }else { mWidth = PxUtils.dpToPx(200,mContext); } if (heightMode == MeasureSpec.EXACTLY) { mHeight = heightSize; }else { mHeight = PxUtils.dpToPx(200,mContext); } Log.e("wing",mWidth+""); setMeasuredDimension(mWidth, mHeight); }自定義屬性attr.xml
<!--{cke_protected}{C}%3C!%2D%2D%3Fxml%20version%3D%221.0%22%20encoding%3D%22utf-8%22%3F%2D%2D%3E--> <resources> <declare-styleable name="PanelView"> <attr name="arcColor" format="color"> <attr name="arcWidth" format="dimension"> <attr name="android:text"> <attr name="tikeCount" format="integer"> <attr name="pointerColor" format="color"> <attr name="android:textSize"> </attr></attr></attr></attr></attr></attr></declare-styleable> </resources>
之後來重頭戲,也就是繪制。就像畫畫一樣,再復雜的view也是一筆一筆畫出來的。所以我們把這個view分解。
大概分解成如下:1.最外面的弧 2.裡面的粗弧 3.中間小圓 4.最小的圓 5.刻度 6.指針 7.矩形 8.文字
相信讓你分開畫一定難不倒你。那組合在一起 就是這個view啦。下面開始我們的ondraw()
按照這個分解來:
1.繪制最外面的弧 這裡需要注意的一點是,如果想讓這個圓在view裡 記得減去畫筆寬度的一半 因為半徑是從圓心到畫筆寬度的中間算的,所以這裡畫弧的矩形是 new RectF(strokeWidth, strokeWidth, mWidth - strokeWidth, mHeight - strokeWidth)
Paint p = new Paint(); int strokeWidth = 3; p.setStrokeWidth(strokeWidth); p.setAntiAlias(true); p.setStyle(Paint.Style.STROKE); p.setColor(mArcColor); //最外面線條 canvas.drawArc(new RectF(strokeWidth, strokeWidth, mWidth - strokeWidth, mHeight - strokeWidth), 145, 250, false, p);
畫出來是這樣的效果。
2.繪制裡面的粗弧,這裡比較麻煩的就是需要分為四段,看圖:
因為大圓和裡面粗弧的長短不一致,這裡使用百分比來計算 所以會造成指針偏差,那麼這裡把 1、2兩個部分固定來畫,然後是3 充滿的部分,用百分比來計算需要畫多少度,最後是4 空白的部分。
首先把粗弧的矩形畫出來,這裡固定了比大弧半徑少50(這裡其實可以改進,你可以改成動態的讓他更靈活),然後計算出百分比。
RectF secondRectF = new RectF(strokeWidth + 50, strokeWidth + 50, mWidth - strokeWidth - 50, mHeight - strokeWidth - 50); float secondRectWidth = mWidth - strokeWidth - 50 - (strokeWidth + 50); float secondRectHeight = mHeight - strokeWidth - 50 - (strokeWidth + 50); float percent = mPercent / 100f;
//充滿的圓弧的度數 -5是大小弧的偏差 float fill = 250 * percent ; //空的圓弧的度數 float empty = 250 - fill; // Log.e("wing", fill + ""); if(percent==0){ p.setColor(Color.WHITE); } //畫粗弧突出部分左端 canvas.drawArc(secondRectF,135,11,false,p);
canvas.drawArc(secondRectF, 145, fill, false, p);
p.setColor(Color.WHITE); //畫弧胡的未充滿部分 canvas.drawArc(secondRectF, 145 + fill, empty, false, p);
//畫粗弧突出部分右端 if(percent == 1){ p.setColor(mArcColor); } canvas.drawArc(secondRectF,144+fill+empty,10,false,p);
3.中間的小圓外圈,他的圓心不用多說 是整個view的中心
p.setColor(mArcColor); //繪制小圓外圈 p.setStrokeWidth(3); canvas.drawCircle(mWidth / 2, mHeight / 2, 30, p);
//繪制小圓內圈 p.setColor(mMinCircleColor); p.setStrokeWidth(8); mMinCircleRadius = 15; canvas.drawCircle(mWidth / 2, mHeight / 2, mMinCircleRadius, p);
5.刻度 刻度處理起來可能比較麻煩,用三角函數算坐標啊 循環畫出來。。 這裡提供一種比較簡單的方法:旋轉畫布。
首先引入一個概念,什麼叫旋轉畫布呢,就是把你的畫布旋轉。。經過測試,旋轉以後,整個坐標軸都會對應旋轉,一張圖舉例說明下。
大概就是這個意思,畫布旋轉之後 坐標系也就旋轉了,但是原來的圖像還在,所以說你比如這個點 x,y旋轉前在這個位置, 那麼旋轉後就是另外一個位置了,但是他們的坐標是相同的。 所以刻度也可以考這種方法畫。我們只要畫出最頂端的刻度 然後旋轉就可以了。
繪制第一段刻度, 然後總共是250的弧度 計算出每個刻度的度數 用250除以刻度數mTikeCount,就是每次旋轉的度數。接下來把畫布逐步旋轉,按照原坐標繪制,即可繪制出右半部分刻度。 注意:為了讓之後的繪制正常,務必把畫布轉回原來的位置
//繪制刻度! p.setColor(mArcColor); //繪制第一條最上面的刻度 mTikeWidth = 20; p.setStrokeWidth(3); canvas.drawLine(mWidth / 2, 0, mWidth / 2, mTikeWidth, p); //旋轉的角度 float rAngle = 250f / mTikeCount; //通過旋轉畫布 繪制右面的刻度 for (int i = 0; i < mTikeCount / 2; i++) { canvas.rotate(rAngle, mWidth / 2, mHeight / 2); canvas.drawLine(mWidth / 2, 0, mWidth / 2, mTikeWidth, p); } //現在需要將將畫布旋轉回來 canvas.rotate(-rAngle * mTikeCount / 2, mWidth / 2, mHeight / 2);
左半部分同理,需要改變的度數為負 就好了
//通過旋轉畫布 繪制左面的刻度 for (int i = 0; i < mTikeCount / 2; i++) { canvas.rotate(-rAngle, mWidth / 2, mHeight / 2); canvas.drawLine(mWidth / 2, 0, mWidth / 2, mTikeWidth, p); } //現在需要將將畫布旋轉回來 canvas.rotate(rAngle * mTikeCount / 2, mWidth / 2, mHeight / 2);
6.指針 指針的繪制和刻度相似,先算出來百分比所占的度數 然後根據 是否大於50%來旋轉畫布。
指針的起終點是 總view高度的一半 粗弧矩形的一半 加上小圓,前面坐標講解了那麼,這個也一樣,自己拿起筆算一算。
注意這裡畫布旋轉我通過計算得出一個公式 250 * percent - 250/2。
如果小於50% 則為負 如果大於50%則為正,然後進行旋轉。
切忌最後一定要將畫布轉回來。
//繪制指針 p.setColor(mMinCircleColor); p.setStrokeWidth(4); //按照百分比繪制刻度 canvas.rotate(( 250 * percent - 250/2), mWidth / 2, mHeight / 2); canvas.drawLine(mWidth / 2, (mHeight / 2 - secondRectHeight / 2) + mScendArcWidth / 2 + 2, mWidth / 2, mHeight / 2 - mMinCircleRadius, p); //將畫布旋轉回來 canvas.rotate(-( 250 * percent - 250/2), mWidth / 2, mHeight / 2);
接下來就是畫矩形和文字。沒什麼好說的了,坐標也是X周圍mWidth/2 y軸自己根據圓心微調一個距離
//繪制矩形 p.setStyle(Paint.Style.FILL); p.setColor(mArcColor); mRectWidth = 60; mRectHeight = 25; //文字矩形的最底部坐標 float rectBottomY = mHeight/2 + secondRectHeight/3+mRectHeight; canvas.drawRect(mWidth/2-mRectWidth/2,mHeight/2 + secondRectHeight/3,mWidth/2+mRectWidth/2,rectBottomY,p); p.setTextSize(mTextSize); mTextColor = Color.WHITE; p.setColor(mTextColor); float txtLength = p.measureText(mText); canvas.drawText(mText,(mWidth-txtLength)/2,rectBottomY + 40,p); super.onDraw(canvas);
這樣完成了整個view的繪制。
下面要做的就是為了方便使用者,提供一些設置屬性的方法。
/** * 設置百分比 * @param percent */ public void setPercent(int percent) { mPercent = percent; invalidate(); } /** * 設置文字 * @param text */ public void setText(String text){ mText = text; invalidate(); } /** * 設置圓弧顏色 * @param color */ public void setArcColor(int color){ mArcColor = color; invalidate(); } /** * 設置指針顏色 * @param color */ public void setPointerColor(int color){ mMinCircleColor = color; invalidate(); } /** * 設置文字大小 * @param size */ public void setTextSize(int size){ mTextSize = size; invalidate(); } /** * 設置粗弧的寬度 * @param width */ public void setArcWidth(int width){ mScendArcWidth = width; invalidate(); }
其實技術的養成也是這樣,只要一步一步腳踏實地的去練習,我相信總有一天我能成為大神,並且找到心儀的工作。
APP遠程調試及網絡自動化測試,app調試自動化1、進入這個網站,注冊並且登錄 https://dt.testbird.com/lo
Android-Universal-Image-Loader (圖片異步加載緩存庫)的源碼解讀 前言: 在Android開發中,對於圖片的加載可以說是個老生常談的問題了,
MSM8909+Android5.1.1之bootloader---修改UART0時鐘頻率致無法下載問題解決 MSM8909+Android5.1.1之bootloade
Android中Canvas繪圖基礎詳解(附源碼下載) Android中,如果我們想繪制復雜的自定義View或游戲,我們就需要熟悉繪圖API。Android通過Canva