轉載請註明作者AndroidMsky和出處
http://blog.csdn.net/AndroidMsky/article/details/53520406
迫不及待拿出了效果圖:
可切換波瀾4種狀態:
https://github.com/AndroidMsky/BitmapWaveView
覺得不錯順手給個star謝謝大兄弟們了
使用方法:
考入BitmapWave還是一個200行的小鬼:
兩個自定義屬性:
<declare-styleable name="bitmapWave">
<attr name="backbitmap" format="reference"/>
<attr name="overColor" format="color"/>
</declare-styleable>
並在佈局中使用:
<com.example.liangmutian.bitmapwaveview.BitmapWave
android:id="@+id/bitmapwave2"
bitmapwave:backbitmap="@mipmap/q1"
bitmapwave:overColor="#eddf0e"
android:layout_width="100dp"
android:layout_height="250dp"
/>
支持修改的屬性:
屬性名稱 | 描述 | 備註 |
---|---|---|
Bitmap bitmap | 背景圖 | |
private int mWaveLength = 700; | 浪寬 | |
private int progerss = 50; | 浪總高 | |
private int mWaveHeight = 80; | 浪振幅高 | |
private float waveBit = 1 / 4f; | 左右浪比例 | 默認1:1 |
private int mWavePaintColor; | 浪顏色 |
方法支持:
mBitmapWave.setMode(1);
值 | 描述 | 備註 |
---|---|---|
0 | 基本波浪 | |
1 | 重疊部分消失 | 可以表示反向加載 |
2 | 浸泡感覺 | |
3 | 紅色覆蓋 | 波浪透明切顏色加深 |
改變顏色
public void setColor(int c) {
mWavePaint.setColor(c);
}
改變進度
public void setProgerss(int c) {
this.progerss = c;
}
原理解析
思路整理
1.將圖像繪製在一個bitmap上
2.繪製背景圖片
3.繪製大波浪
4.用特定的畫筆類型繪製
5.用value動畫讓波浪動起來
6.提供設計設置進度,設置顏色等方法和xml屬性標籤
難點解析
通過ValueAnimator產生差值並重回view產生波浪:
ValueAnimator animator = ValueAnimator.ofInt(0, mWaveLength);
animator.setDuration(1000);
animator.setRepeatCount(ValueAnimator.INFINITE);
animator.setInterpolator(new LinearInterpolator());
animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
mOffset = (int) animation.getAnimatedValue();
postInvalidate();
}
});
animator.start();
繪製波瀾path源自貝塞爾曲線:
mPath.reset();
mPath.moveTo(-mWaveLength + mOffset, mCenterY);
for (int i = 0; i < mWaveCount; i++) {
mPath.quadTo((-mWaveLength * (1 - waveBit)) + (i * mWaveLength) + mOffset, mCenterY + mWaveHeight,
(-mWaveLength / 2) + (i * mWaveLength) + mOffset, mCenterY);
mPath.quadTo((-mWaveLength * waveBit) + (i * mWaveLength) + mOffset, mCenterY - mWaveHeight, i * mWaveLength + mOffset, mCenterY);
}
mPath.lineTo(mWidth, mHeight);
mPath.lineTo(0, mHeight);
mPath.close();
貝塞爾曲線還不瞭解的可以看一下醫生的一篇貝塞爾的文章很全。
關鍵在玩轉16中畫筆
private PorterDuffXfermode mMode3 = new PorterDuffXfermode(PorterDuff.Mode.MULTIPLY);//透明出來
//private PorterDuffXfermode mMode = new PorterDuffXfermode(PorterDuff.Mode.XOR);//紅色覆蓋
private PorterDuffXfermode mMode2 = new PorterDuffXfermode(PorterDuff.Mode.DST_ATOP);//浸泡感覺
private PorterDuffXfermode mMode1 = new PorterDuffXfermode(PorterDuff.Mode.DST_OUT);//重疊部分消失 可以表示反向加載
private PorterDuffXfermode mMode0 = new PorterDuffXfermode(PorterDuff.Mode.SRC_IN);//基本波浪
提供更改高畫筆類型方法:
public void setMode(int c) {
switch (c) {
case 0:
mWavePaint.setXfermode(mMode0);
break;
case 1:
mWavePaint.setXfermode(mMode1);
break;
case 2:
mWavePaint.setXfermode(mMode2);
break;
case 3:
mWavePaint.setXfermode(mMode3);
break;
}
}
簡簡單單的介紹完了。