效果图
先上效果图
实现
ProgressWaveView的属性
Wate Level(水位)
波浪静止时水面距离底部的高度
Amplitude(振幅)
波浪垂直振动时偏离水面的最大距离
Wave Length(波长)
一个完整的波浪的水平长度
Wave Shift(偏移)
波浪相对于初始位置的水平偏移
真实效果图
1. 圆形效果图
2. 框形效果图
实现思路
设想我们有一个画好波形的图片,那么我们只需要用这张图片填充(X轴方向重复,Y轴方向延伸)整个View,然后水平移动图片,就可以得到波浪效果了。
所以要做的事很简单:绘制一个波形图,填充到View里,移动波形图。
1. 绘制初始波形
private void createShader() {
...
Bitmap bitmap = Bitmap.createBitmap(getWidth(), getHeight(), Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
// Draw default waves into the bitmap
// y=Asin(ωx+φ)+h
float waveX1 = 0;
final float wave2Shift = mDefaultWaveLength / 4;
final float endX = getWidth();
final float endY = getHeight();
...
while (waveX1 < endX) {
double wx = waveX1 * mDefaultAngularFrequency;
int startY = (int) (mDefaultWaterLevel + mDefaultAmplitude * Math.sin(wx));
// draw bottom wave with the alpha 40
canvas.drawLine(waveX1, startY, waveX1, endY, wavePaint1);
// draw top wave with the alpha 60
float waveX2 = (waveX1 + wave2Shift) % endX;
canvas.drawLine(waveX2, startY, waveX2, endY, wavePaint2);
waveX1++;
}
// use the bitamp to create the shader
mWaveShader = new BitmapShader(bitmap, Shader.TileMode.REPEAT, Shader.TileMode.CLAMP);
mViewPaint.setShader(mWaveShader);
}
首先一个长宽恰等于WaveView的Bitmap:Bitmap.createBitmap(getWidth(), getHeight(), Bitmap.Config.ARGB_8888)
。
在Bitmap中使用默认的属性绘制出初始波形。初始波形的属性:Wate Level(水位)为WaveView高度的1/2;Amplitude(振幅)为WaveView高度的1/20;Wave Length(波长)等于WaveView的宽度。
绘制好的初始波形是下面这个样子:
初始波形
代码第 9 ~ 27 行进行初始波形的绘制。波形由wave1和wave2两个波组成,wave2就是wave1向左偏移1/4的wave length,所以不需要重复计算。
最后把这个Bitmap设置成为Paint的Shader。设置Shader相当于设定画笔的形状,使用设置了Shader的Paint绘制图形时,实际上是在使用Bitmap填充绘制的区域。X轴的填充方式为TileMode.REPEAT
,即重复填充;Y轴的填充方式为TileMode.CLAMP
,即使用边缘的色值延伸填充。
2. 调整Bitmap的大小并填充到WaveView
有了初始波形,当WaveView的属性改变时,只需要对初始波形进行相应的拉伸/压缩和位移就可以得到用户想要的波形。
3. 动画
效果就是波形一直在波动。