(Android自定義View)來來來,一起再擼一個Material風格loadingView。
本文同步自博主的個人部落格wing的地方酒館
很久很久以前,擼了一款loadingview(點選這裡回顧),當時覺得還不錯,現在看看覺得好醜啊!!! 於是想再擼一個,無意間在這裡看到一個很不錯的效果,於是手癢了,就想動動手,算起來,也有很久沒有寫過View了。
效果圖
哈,可能又是我自我感覺良好,覺得效果還不錯,不過沒準再過半年我又嫌棄之前的自己了 哈哈哈。
還有呢,如果你看這篇比較吃力,推薦先去看看我之前學view的時候寫的一些部落格,難度是一點一點增加的。
簡單說說自定義view的學習方式
實現思路
看到效果,首先要分析,這裡主要是什麼組成的。
首先吶,肯定要畫兩個圓圈,對吧? 不要告訴我你不會畫圓。如果不會,請看上面的連結。
private void drawCircle(Canvas canvas, float present) {
canvas.drawCircle(mWidth / 2, mHeight / 2 -mMaxOffset, mMaxRadius, mPaint);
canvas.drawCircle(mWidth / 2, mHeight / 2 + mMaxOffset, mMaxRadius, mPaint);
}
然後想辦法讓圈圈轉起來,怎麼轉起來呢,肯定是rotate方法了~~這裡提供一個角度引數,讓他自增,如果到360呢,就讓他等於0,然後invalidate(),就可以實現圈圈轉動的效果。
canvas.rotate(mDegrees += 3, mWidth / 2, mHeight / 2);
if (mDegrees == 360) {
mDegrees = 0;
}
invalidate();
恩。。已經轉起來了。
接下來要想辦法讓兩個小圓在轉圈的過程中靠近,再遠離,怎麼實現呢?注意上面讓小圓有間隔的mMaxOffset!我們可以根據旋轉的百分比來動態改變這個offset!
所以,要改一下drawCircle()程式碼
float present = mDegrees / 360;
if (present < 0.5 ) {
mOffset = mMaxOffset * present;
} else {
mOffset = mMaxOffset * (1 - present);
}
private void drawCircle(Canvas canvas) {
canvas.drawCircle(mWidth / 2, mHeight / 2 - mOffset, mMaxRadius, mPaint);
canvas.drawCircle(mWidth / 2, mHeight / 2 + mOffset, mMaxRadius, mPaint);
}
現在是這樣,恩..已經有點效果了。
那小圈靠近的時候,粘合動畫怎麼做?還記得qq訊息點去除嗎?跟那個道理一樣!!! 就是畫一個貝塞爾的path。座標計算思路在模仿qq訊息去除效果 這裡思路是一樣的,只不過微調了輔助點座標。直接上程式碼:
if (present <= 0.37 || present >= 0.63) drawPath(canvas, present);
private void drawPath(Canvas canvas, float present) {
mPath.reset();
mPath.moveTo(mWidth / 2 - mMaxRadius, mHeight / 2 - mOffset);
mPath.lineTo(mWidth / 2 + mMaxRadius, mHeight / 2 - mOffset);
float supportOffset = -30;
if (present < 0.25) { //兩個球相交
supportOffset = 30;
} else if (present >= 0.25 && present < 0.375f) {
Log.e("present", present + "");
supportOffset = -(480 * present - 150f);
} else if (present > 0.625) { //開始縮小
supportOffset = (480 * present - 330f);
if (present > 0.75) { //兩個球開始相交
supportOffset = 30;
}
//supportOffset = 30;
}
Log.e("wing", supportOffset + "");
mPath.quadTo(mWidth / 2 + supportOffset, mHeight / 2, mWidth / 2 + mMaxRadius,
mHeight / 2 + mOffset);
mPath.lineTo(mWidth / 2 - mMaxRadius, mHeight / 2 + mOffset);
mPath.quadTo(mWidth / 2 - supportOffset, mHeight / 2, mWidth / 2 - mMaxRadius,
mHeight / 2 - mOffset);
mPath.close();
mPaint.setStyle(Paint.Style.FILL);
canvas.drawPath(mPath, mPaint);
}
有一點值得注意的是,輔助點偏移座標和percent的關係。以 supportOffset = -(480 * present - 150f);作為說明。這個方程式怎麼得出出來的呢。 因為我想讓百分比從0.25->0.375變化,而輔助點座標從-30->30變化,所以是一個簡單的初中數學中的線性方程。將k和b帶入 y = kx +b 即可輕易得出。
之後在根據percent控制path的顯隱,即可實現最上效果圖的效果。
如果你感興趣,可以下載原始碼研究下~~當然,如果覺得贊,點個star是對我最大的支援~