国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 系統 > Android > 正文

Android自定義view實現水波進度條控件

2019-10-22 18:11:09
字體:
來源:轉載
供稿:網友

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

Android,view,進度條

一.用法

1.布局文件中添加WaveProgressView,circleColor屬性為圓環顏色,waterColor屬性為水波水滴的顏色,progress屬性為初始的進度

<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()方法設置當前的進度

二.本文實現的邏輯

1,畫水波流動,通過三階貝塞爾曲線畫波形,通過不斷的改變waveOffsetX和waveOffsetY的值實現流動的效果

/**   * 生成水波流動   *   * @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.畫水滴的形狀,水滴的形狀是通過一個三角形和一個弧形組成的

/**   * 水滴的Path   *   * @param x  水滴坐標x   * @param y  水滴坐標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軸不斷的移動水滴

/**   * 根據位置畫水滴   *   * @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.畫最外兩側濺落的水滴,通過三階貝塞爾曲線模擬左右兩側水滴濺落的路徑,隨機生成的水滴濺落路徑都在這左右兩側內

 

/**   * 畫兩側水滴飛濺的效果,并且隨機生成水滴   *   * @param canvas   * @param x   * @param y   當前高度   */  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);}
/**   * 產生隨機的水滴   *   * @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);//左右差值加上最小值,保證隨機值在兩者之間        mRandomHashMap.put(randomX, randomY);      }    }}

5.隨機生成的水滴沿著三階貝塞爾曲線移動,形成濺落的效果

/**   * 畫隨機生成水滴濺起   *   * @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);  }

完整代碼詳見 點擊打開Github本項目 感興趣的話幫我點個Star

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持VEVB武林網。


注:相關教程知識閱讀請移步到Android開發頻道。
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 通化县| 宝应县| 仁化县| 湖南省| 东乡| 武安市| 蓝田县| 斗六市| 盐边县| 方山县| 枣庄市| 宜阳县| 眉山市| 凤庆县| 神农架林区| 杭锦旗| 永济市| 昆山市| 安多县| 榆社县| 加查县| 兴城市| 大足县| 华安县| 高陵县| 中阳县| 柏乡县| 施甸县| 虹口区| 彰化市| 绥滨县| 绥德县| 册亨县| 翁牛特旗| 岳西县| 新沂市| 神农架林区| 兴安县| 伊春市| 西昌市| 孟州市|