Android自定義view實(shí)現(xiàn)水波進(jìn)度條控件
通過自定義view實(shí)現(xiàn)了一個(gè)水滴滴落到水波面,濺起水花并且水波流動(dòng)上漲的進(jìn)度條控件。之前看到過好多水波流動(dòng)的進(jìn)度條,感覺欠缺些東西,就想到了水滴到水平面,濺起水花然后水流動(dòng)上漲的進(jìn)度條效果,于是自己動(dòng)手寫了出來。效果如下,視頻錄制有些卡頓,實(shí)際會(huì)流暢很多。

一.用法
1.布局文件中添加WaveProgressView,circleColor屬性為圓環(huán)顏色,waterColor屬性為水波水滴的顏色,progress屬性為初始的進(jìn)度
<com.yhongm.wave_progress_view.WaveProgressView android:id="@+id/wave_progress_view" android:layout_width="300dp" android:layout_height="300dp" android:layout_centerInParent="true" app:circleColor="#e38854" app:progress="0" app:waterColor="#5488e3" />
2.WaveProgressView.setProgress()方法設(shè)置當(dāng)前的進(jìn)度
二.本文實(shí)現(xiàn)的邏輯
1,畫水波流動(dòng),通過三階貝塞爾曲線畫波形,通過不斷的改變waveOffsetX和waveOffsetY的值實(shí)現(xiàn)流動(dòng)的效果
/**
* 生成水波流動(dòng)
*
* @param begin 水波形開始的位置
* @param waveLength 水波的長度
* @param waveOffsetX 水波水平的偏移
* @param waveOffsetY 水波垂直方向的偏移
* @return
*/
private Path getWavePath(float begin, int waveLength, int waveOffsetX, int waveOffsetY) {
Path mPath = new Path();
mPath.reset();
mPath.moveTo(waveLength * begin, mCurrentHeight);
for (int i = 0; i < mWaveCount; i++) {
mPath.quadTo(waveLength * (begin + 0.25f) + (i * waveLength) + waveOffsetX, mCurrentHeight + waveOffsetY, (waveLength * (begin + 0.5f) + (i * waveLength) + waveOffsetX), mCurrentHeight);
mPath.quadTo(waveLength * (begin + 0.75f) + (i * waveLength) + waveOffsetX, mCurrentHeight - waveOffsetY, (waveLength * (begin + 1f) + (i * waveLength) + waveOffsetX), mCurrentHeight);
}
mPath.lineTo(mWidth, mHeight);
mPath.lineTo(0, mHeight);
mPath.close();
return mPath;
}
2.畫水滴的形狀,水滴的形狀是通過一個(gè)三角形和一個(gè)弧形組成的
/**
* 水滴的Path
*
* @param x 水滴坐標(biāo)x
* @param y 水滴坐標(biāo)y
* @param size 水滴尺寸
* @return
*/
private Path waterDrop(float x, float y, int size) {
Path mDropPath = new Path();
mDropPath.moveTo(x - size, y);
mDropPath.lineTo(x, (float) (y - size * 2.5));
mDropPath.lineTo(x + size, y);
mDropPath.addArc(x - size, y - size, x + size, y + size, 0, 180);
return mDropPath;
}
3.畫水滴滴落到水波的效果,就是沿軸Y軸不斷的移動(dòng)水滴
/**
* 根據(jù)位置畫水滴
*
* @param x
* @param y
* @param canvas
*/
private void drawDropByLocation(Canvas canvas, int x, int y) {
Path mDropPath = waterDrop(x, y, 30);
if (y == (mCurrentHeight + 50)) {
mDropPaint.setAlpha(0);
}
canvas.drawPath(mDropPath, mDropPaint);
}
4.畫最外兩側(cè)濺落的水滴,通過三階貝塞爾曲線模擬左右兩側(cè)水滴濺落的路徑,隨機(jī)生成的水滴濺落路徑都在這左右兩側(cè)內(nèi)
/**
* 畫兩側(cè)水滴飛濺的效果,并且隨機(jī)生成水滴
*
* @param canvas
* @param x
* @param y 當(dāng)前高度
*/
private synchronized void drawDropSplash(Canvas canvas, int x, int y) {
PathMeasure mLeftPathMeasure = getOnBothSidesOfPathMeasure(x, y, true);
PathMeasure mRightPathMeasure = getOnBothSidesOfPathMeasure(x, y, false);
float[] mLeftPos = new float[2];
float[] mRightPos = new float[2];
float[] mLeftTan = new float[2];
float[] mRightTan = new float[2];
for (int i = 0; i < 200; i++) {
float percent = i / 200f;
mLeftPathMeasure.getPosTan(mLeftPathMeasure.getLength() * percent, mLeftPos, mLeftTan);
mRightPathMeasure.getPosTan(mRightPathMeasure.getLength() * percent, mRightPos, mRightTan);
mLeftHashMapPath.put(Math.round(mLeftPos[1]), mLeftPos[0]);
mRightHashMapPath.put(Math.round(mRightPos[1]), mRightPos[0]);
}
if (mRandomHashMap.isEmpty() && mRandomHashMap.size() == 0) {
pushRandomDrag(y);
}
drawRandomDrag(canvas, x, y, mLeftHashMapPath, mRightHashMapPath);
drawOnBothSidesOfWaterDrop(canvas, mLeftPathMeasure);
drawOnBothSidesOfWaterDrop(canvas, mRightPathMeasure);
}
/**
* 產(chǎn)生隨機(jī)的水滴
*
* @param y
*/
private void pushRandomDrag(int y) {
Random r = new Random();
for (int i = 0; i < 20; i++) {
int randomY = r.nextInt(y);
if (mLeftHashMapPath.containsKey(randomY)) {
Float rightValue = mRightHashMapPath.get(randomY);
Float leftValue = mLeftHashMapPath.get(randomY);
int roundLeftValue = Math.round(leftValue);
int roundRightValue = Math.round(rightValue);
if (roundRightValue == roundLeftValue) {
roundRightValue++;
}
int roundMinus = Math.round(roundRightValue - roundLeftValue);//左右差值
float randomX = r.nextInt(roundMinus) + mLeftHashMapPath.get(randomY);//左右差值加上最小值,保證隨機(jī)值在兩者之間
mRandomHashMap.put(randomX, randomY);
}
}
}
5.隨機(jī)生成的水滴沿著三階貝塞爾曲線移動(dòng),形成濺落的效果
/**
* 畫隨機(jī)生成水滴濺起
*
* @param canvas
* @param x
* @param y
* @param size
* @param randomY
* @param randomX
*/
private void drawSmartDropOnPath(Canvas canvas, int x, int y, int size, int randomY, float randomX) {
Path smartDropPath = new Path();
smartDropPath.moveTo(x, y + 50);
if (x < randomX) {
smartDropPath.cubicTo(x, y + 50, randomX + 30, randomY - 20, randomX, randomY);
} else {
smartDropPath.cubicTo(x, y + 50, randomX - 30, randomY - 20, randomX, randomY);
}
smartDropPath.lineTo(randomX, randomY + 150);
PathMeasure pathMeasure = new PathMeasure();
pathMeasure.setPath(smartDropPath, false);
float[] pos = new float[2];
float[] tan = new float[2];
pathMeasure.getPosTan(pathMeasure.getLength() * mPercent, pos, tan);
Path path = waterDrop(pos[0], pos[1], size);
canvas.drawPath(path, mSplashPaint);
}
完整代碼詳見 點(diǎn)擊打開Github本項(xiàng)目 感興趣的話幫我點(diǎn)個(gè)Star
以上就是本文的全部內(nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
- Android仿微信加載H5頁面進(jìn)度條
- android實(shí)現(xiàn)快遞跟蹤進(jìn)度條
- Android自定義View實(shí)現(xiàn)漸變色進(jìn)度條
- Android自定義View實(shí)現(xiàn)加載進(jìn)度條效果
- Android 七種進(jìn)度條的樣式
- Android中實(shí)現(xiàn)Webview頂部帶進(jìn)度條的方法
- android自定義進(jìn)度條漸變色View的實(shí)例代碼
- Android文件下載進(jìn)度條的實(shí)現(xiàn)代碼
- android ListView和ProgressBar(進(jìn)度條控件)的使用方法
- Android仿微信公眾號(hào)文章頁面加載進(jìn)度條
相關(guān)文章
Kotlin作用域函數(shù)應(yīng)用詳細(xì)介紹
作用域函數(shù):是Kotlin標(biāo)準(zhǔn)庫中的內(nèi)聯(lián)函數(shù),作用在對(duì)象上時(shí),執(zhí)行給定的block代碼塊??梢栽赽lock代碼塊中通過it,this代表當(dāng)前對(duì)象,進(jìn)行代碼邏輯處理2022-08-08
Android Notification的多種用法總結(jié)
這篇文章主要介紹了Android Notification的多種用法總結(jié)的相關(guān)資料,需要的朋友可以參考下2017-06-06
Android數(shù)據(jù)傳輸中的參數(shù)加密代碼示例
這篇文章主要介紹了Android數(shù)據(jù)傳輸中的參數(shù)加密代碼示例,具有一定參考價(jià)值,需要的朋友可以了解下。2017-11-11
Android 二維碼 生成和識(shí)別二維碼 附源碼下載
這篇文章主要介紹了Android 生成和識(shí)別二維碼的方法,提供源碼下載,需要的朋友可以參考下。2016-06-06
Android編程實(shí)現(xiàn)自定義輸入法功能示例【輸入密碼時(shí)防止第三方竊取】
這篇文章主要介紹了Android編程實(shí)現(xiàn)自定義輸入法功能,可實(shí)習(xí)輸入密碼時(shí)防止第三方竊取的效果,結(jié)合實(shí)例形式詳細(xì)分析了Android布局、控件及輸入法相關(guān)操作技巧,需要的朋友可以參考下2017-01-01
Android開發(fā)中父組件調(diào)用子組件方法demo
這篇文章主要為大家介紹了Android開發(fā)中父組件調(diào)用子組件方法demo,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-12-12
android實(shí)現(xiàn)自動(dòng)滾動(dòng)的Gallary控件效果
這篇文章主要介紹了android實(shí)現(xiàn)自動(dòng)滾動(dòng)的Gallary控件效果,涉及Android中Gallary控件的相關(guān)使用技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下2015-10-10

