編輯:Android開發教程
技術是永無止境的,如果真的愛技術,那就勇敢的堅持下去。我很喜歡這句話,當我在遇到問題的時候、當我覺得代碼枯燥的時候,我就會問自己,到底是不是真的熱愛技術,這個時候,我心裡總是起著波瀾,我的答案是肯定的,我深深的愛著這門技術。
今天我們繼續聊聊Android的自定義View系列。先看看效果吧:

這個是我手機殺毒軟件的一個動畫效果,類似於雷達搜索,所以用途還是很廣泛的,特別是先了解一下這裡的具體邏輯和寫法,對技術的進步一定很有用。
先簡單的分析一下這裡的元素,主要有四個圓、一個扇形、還有八條虛線。當知道這些以後,代碼就可以開始寫了。
先看看這裡用到了哪些變量。
mWidth;
mHeight;
Paint mPaint, mPaint2, mPaint3, mPaint4, mLinePaint;
RectF mRectF;
startAngle = ;
radius1, radius2, radius3, radius4;
Path path;
不是很多,有畫筆6個,然後是寬與高,還有就是角度以及四個圓的半徑以及一個矩形、當然還有繪制虛線的Path類。接下來是初始化的操作。
// 初始化畫筆操作
private void initData() {
mPaint = new Paint()
mPaint()
mPaint(true)
mPaint(Style)
mPaint(Color())
mPaint2 = new Paint()
mPaint2()
mPaint2(Color())
mPaint3 = new Paint()
mPaint3()
mPaint3(true)
mPaint3(Style)
mPaint3(Color())
mPaint4 = new Paint()
mPaint4()
mPaint4(true)
mPaint4(Style)
mPaint4(Color())
mLinePaint = new Paint(Paint_ALIAS_FLAG)
mLinePaint()
mLinePaint(Paint)
mLinePaint(true)
mLinePaint(Color())
path = new Path()
}
這裡包括了五個畫筆的初始化操作、一個路徑的初始化操作。注意每個畫筆的具體樣式是不一樣的,這樣方便實現不同的效果。
初始化的操作完了之後,就是給變量賦值了,還是一樣的,我們選擇在onSizeChange()裡面對變量進行賦值。代碼如下:
( w, h, oldw, oldh) {
.onSizeChanged(w, h, oldw, oldh);
mWidth = getWidth();
mHeight = getHeight();
mRectF = RectF(() (mWidth * ), () (mWidth * ),
() (mWidth * ), () (mWidth * ));
LinearGradient gradient = LinearGradient(() (mWidth * ),
() (mWidth * ), () (mWidth * ),
() (mWidth * ), [] {
Color.parseColor(), Color.GREEN,
Color.parseColor(), Color.WHITE,
Color.parseColor() }, ,
Shader.TileMode.CLAMP);
mPaint2.setShader(gradient);
radius1 = () (mWidth * );
radius2 = () (mWidth * );
radius3 = () (mWidth * );
radius4 = () (mWidth * );
}
其實很明顯啊,我們在前面講的幾個自定義的View中,幾乎所有的變量初值都是在這個方法裡面寫的,這個方法究竟有什麼特點呢?其實這個是系統回調方法,是系統調用的,它的方法名已經告訴我們了,這個方法會在這個view的大小發生改變是被系統調用,我們要記住的就是view大小變化,這個方法就被執行就可以了。最主要的是,它還在onDraw方法之前調用。
還記得之前的效果嗎?裡面有一個漸變,這個漸變就是代碼裡LinearGradient 類的操作結果了,具體的用法,我在後面會專門去解釋它。
到了這裡,基本上所有的准備工作都完成了,接下來進行真真的繪圖。
先看看onDraw方法裡面做的操作:
protected void onDraw(Canvas ) {
super.onDraw();
canvasArc();
canvasArc2();
canvasCircle();
canvasLine();
}
這裡有畫圓的,有畫扇形的,也有畫線的,所以可以發現,我們所有看到的效果,都是在onDraw方法裡面實現的。我們具體看看每一個方法:
第一個繪制扇形:
(Canvas canvas) {
canvas.drawArc(mRectF, startAngle, , , mPaint2);
}
只有兩行代碼,也很容易理解,那麼第二個扇形也是差不多:
(Canvas canvas) {
canvas.drawArc(mRectF, startAngle, , , mPaint3);
}
值得注意的是,第二個的扇形的角度是1,為什麼是1呢,原來我這裡只是想要它旋轉角度的效果,並不需要它有多寬,所以在具體實現自定義View的時候,也要學會活學活用。
兩個扇形已經畫好了,那就看看四個圓怎麼畫:
private void canvasCircle(Canvas ) {
.drawCircle(mWidth / , mHeight / , radius1, mPaint3);
.drawCircle(mWidth / , mHeight / , radius2, mPaint);
.drawCircle(mWidth / , mHeight / , radius3, mPaint);
.drawCircle(mWidth / , mHeight / , radius4, mPaint4);
}
四個圓就是四行代碼,怎麼樣,很簡單吧?
注意他們所用的畫筆是不太一樣的,這裡是比較容易忽視的地方。
最後來看看我糾結很久的畫虛線的操作,這裡真是把我卡了好一會兒,先看看代碼:
(Canvas canvas) {
lineCount = ;
( i = ; i < lineCount; i++) {
path.moveTo(mWidth / , mHeight / );
path.lineTo(radius1, radius4);
PathEffect effects = DashPathEffect( [] {
() (mWidth * ), () (mWidth * ),
() (mWidth * ), () (mWidth * ) }, );
mLinePaint.setPathEffect(effects);
canvas.drawPath(path, mLinePaint);
canvas.rotate(, mWidth / , mHeight / );
}
}
按理說,繪制虛線,本質也是畫線,但是我一開始是用canvas.drawLine方法,但是沒有效果,網上查找了資料,才知道可能是版本的問題,於是我換用了path。
到了這個時候,全部效果已經出來了,那麼為了讓她動起來,我們還是要加點邏輯,我的思路是這樣的:
定義一個線程,然後通過改變扇形的開始角度來實現動畫的效果。
代碼如下:
{
@Override
run() {
() {
(running) {
SystemClock.sleep();
handler.sendEmptyMessage();
}
}
}
}
running = ;
Handler handler = Handler() {
handleMessage(android.os.Message msg) {
synchronized () {
(startAngle < ) {
startAngle = ;
} {
startAngle--;
invalidate();
}
}
};
};
Android開發入門(十一)選擇控件 11.1 TimePicker
使用TimePicker,可以讓用戶去選擇一天中的事件,包括24小時制和AM/PM制。下面的例子將會展示如何 使用TimePicker。1. 創建一個工程:BasicVi
Appium移動自動化測試(三) 安裝Android模擬器
本文中如果直接安裝時不出現錯誤,則可以忽略(一、二、三、四、五),我安裝的是5.1.1,直接成功,就是有點慢,要有耐心。如果到最後一步,啟動不起來,報錯:emulator
Android開發入門(四)發送通知 4.1 Toast通知
Toast通知是Android中最簡單的消息通知。接下來展示如何使用吐司通知。1. 新建一個工程, Toast。2. main.xml中的代碼。<RelativeL
Android中使用SearchView時軟鍵盤不支持actionSearch的問題
變態問題常有,今年特別多,,, - - # 今天遇到的這個非處理不可,不然沒法在HTC One S使用SearchView,其軟鍵盤不支持action設置。問題設備:HT