Skip to content

Commit fca3c58

Browse files
committed
自定义水波动画
1 parent 3e1364a commit fca3c58

6 files changed

Lines changed: 314 additions & 26 deletions

File tree

.idea/misc.xml

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
package com.allen.androidcustomview.bean;
2+
3+
/**
4+
* Created by allen on 2016/12/14.
5+
* 水波参数的实体
6+
*/
7+
8+
public class WaveBean {
9+
10+
private int waveLength;
11+
12+
private int offset;
13+
private int startOffset;
14+
15+
private int waveRepeatCount;
16+
17+
public WaveBean(int waveLength, int startOffset) {
18+
this.waveLength = waveLength;
19+
this.startOffset = startOffset;
20+
}
21+
22+
public int getStartOffset() {
23+
return startOffset;
24+
}
25+
26+
public void setStartOffset(int startOffset) {
27+
this.startOffset = startOffset;
28+
}
29+
30+
public int getWaveRepeatCount() {
31+
return waveRepeatCount;
32+
}
33+
34+
public void setWaveRepeatCount(int waveRepeatCount) {
35+
this.waveRepeatCount = waveRepeatCount;
36+
}
37+
38+
public int getWaveLength() {
39+
return waveLength;
40+
}
41+
42+
public void setWaveLength(int waveLength) {
43+
this.waveLength = waveLength;
44+
}
45+
46+
public int getOffset() {
47+
return offset;
48+
}
49+
50+
public void setOffset(int offset) {
51+
this.offset = offset;
52+
}
53+
}
Lines changed: 208 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,18 @@
11
package com.allen.androidcustomview.widget;
22

3+
import android.animation.ValueAnimator;
34
import android.content.Context;
5+
import android.content.res.TypedArray;
46
import android.graphics.Canvas;
7+
import android.graphics.LinearGradient;
58
import android.graphics.Paint;
9+
import android.graphics.Path;
10+
import android.graphics.Shader;
611
import android.util.AttributeSet;
712
import android.view.View;
13+
import android.view.animation.LinearInterpolator;
14+
15+
import com.allen.androidcustomview.R;
816

917
/**
1018
* Created by allen on 2016/12/13.
@@ -14,51 +22,236 @@
1422

1523
public class WaveView extends View {
1624

17-
private Paint paint;
25+
/**
26+
* 上下文对象
27+
*/
28+
private Context mContext;
29+
/**
30+
* 屏幕高度
31+
*/
32+
private int mScreenHeight;
33+
/**
34+
* 屏幕宽度
35+
*/
36+
private int mScreenWidth;
37+
38+
/**
39+
* 波浪的画笔
40+
*/
41+
private Paint mWavePaint;
42+
/**
43+
* 一个周期波浪的长度
44+
*/
45+
private int mWaveLength;
46+
/**
47+
* 一个周期波浪的默认长度
48+
*/
49+
private int mdefaultWaveLength = 500;
50+
51+
/**
52+
* 屏幕宽度内波浪显示几个周期
53+
*/
54+
private int mWaveCount;
55+
56+
/**
57+
* 波纹的中间轴(基准线)
58+
*/
59+
private int mCenterY;
60+
/**
61+
* 波浪的路径
62+
*/
63+
Path mWavePath;
64+
65+
/**
66+
* 平移偏移量
67+
*/
68+
private int mOffset;
69+
70+
/**
71+
* 渐变色shader
72+
*/
73+
private Shader mShader;
74+
/**
75+
* 渐变色shade配置参数
76+
*/
77+
private int colors[] = new int[2];
78+
79+
/**
80+
* 渐变波开始的颜色
81+
*/
82+
private int mWaveStartColor;
83+
84+
/**
85+
* 渐变波结束的颜色
86+
*/
87+
private int mWaveEndColor;
88+
89+
/**
90+
* 颜色渐变波默认开始颜色
91+
*/
92+
private int mWaveDefaultStartColor;
93+
/**
94+
* 颜色渐变波默认结束颜色
95+
*/
96+
private int mWaveDefaultEndColor;
97+
98+
/**
99+
* 振幅
100+
*/
101+
private int mWaveAmplitude;
102+
103+
/**
104+
* 水波动画延时
105+
*/
106+
private int mWaveDuration;
107+
108+
private boolean mWaveFillTop;
18109

19-
private float lineX0;
20-
private float lineY0;
110+
private boolean mWaveFillBottom;
21111

22-
private float lineX1;
23-
private float lineY1;
24112

25113
public WaveView(Context context) {
26-
super(context);
27-
init();
114+
this(context, null);
28115
}
29116

30117
public WaveView(Context context, AttributeSet attrs) {
31-
super(context, attrs);
32-
init();
118+
this(context, attrs, 0);
33119
}
34120

35121
public WaveView(Context context, AttributeSet attrs, int defStyleAttr) {
36122
super(context, attrs, defStyleAttr);
123+
mContext = context;
124+
mWaveDefaultStartColor = getResources().getColor(R.color.wave_start);
125+
mWaveDefaultEndColor = getResources().getColor(R.color.wave_end);
126+
getAttr(attrs);
37127
init();
38128
}
39129

130+
private void getAttr(AttributeSet attrs) {
131+
TypedArray typedArray = mContext.obtainStyledAttributes(attrs, R.styleable.WaveView);
132+
133+
mWaveLength = typedArray.getDimensionPixelOffset(R.styleable.WaveView_waveLength, mdefaultWaveLength);
134+
mWaveDuration = typedArray.getDimensionPixelOffset(R.styleable.WaveView_waveDuration, 2000);
135+
mWaveAmplitude = typedArray.getDimensionPixelOffset(R.styleable.WaveView_waveAmplitude, dip2px(mContext, 20));
136+
mWaveStartColor = typedArray.getColor(R.styleable.WaveView_waveStartColor, mWaveDefaultStartColor);
137+
mWaveEndColor = typedArray.getColor(R.styleable.WaveView_waveEndColor, mWaveDefaultEndColor);
138+
139+
mWaveFillTop = typedArray.getBoolean(R.styleable.WaveView_mWaveFillTop, true);
140+
mWaveFillBottom = typedArray.getBoolean(R.styleable.WaveView_mWaveFillBottom, false);
141+
142+
typedArray.recycle();
143+
}
144+
40145
private void init() {
41146
initPaint();
42-
147+
Animation();
43148
}
44149

150+
45151
/**
46152
* 初始化画笔
47153
*/
48154
private void initPaint() {
49-
paint = new Paint();
50-
paint.setStrokeWidth(5);
51-
paint.setStyle(Paint.Style.STROKE);
52-
paint.setAlpha(60);
53-
paint.setAntiAlias(true);
155+
156+
mWavePath = new Path();
157+
158+
colors[0] = mWaveStartColor;
159+
colors[1] = mWaveEndColor;
160+
161+
mWavePaint = new Paint();
162+
163+
mWavePaint.setStrokeWidth(1);
164+
mWavePaint.setStyle(Paint.Style.FILL_AND_STROKE);
165+
mWavePaint.setAntiAlias(true);
166+
54167
}
55168

56169

170+
@Override
171+
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
172+
super.onSizeChanged(w, h, oldw, oldh);
173+
mScreenHeight = h;
174+
mScreenWidth = w;
175+
176+
mWaveCount = (int) Math.round(mScreenWidth / mWaveLength + 1.5);
177+
178+
mCenterY = mScreenHeight - mWaveAmplitude;
179+
180+
}
181+
57182
@Override
58183
protected void onDraw(Canvas canvas) {
59184
super.onDraw(canvas);
60185

186+
mShader = new LinearGradient(0, 0, getWidth(), 0, colors, null, Shader.TileMode.CLAMP);
187+
mWavePaint.setShader(mShader);
188+
189+
drawWave(canvas);
190+
}
191+
192+
private void drawWave(Canvas canvas) {
193+
mWavePath.reset();
194+
mWavePath.moveTo(-mWaveLength + mOffset, mCenterY);
195+
196+
for (int i = 0; i < mWaveCount; i++) {
197+
mWavePath.quadTo((-mWaveLength * 3 / 4) + (i * mWaveLength) + mOffset, mCenterY + mWaveAmplitude, (-mWaveLength / 2) + (i * mWaveLength) + mOffset, mCenterY);
198+
mWavePath.quadTo((-mWaveLength / 4) + (i * mWaveLength) + mOffset, mCenterY - mWaveAmplitude, i * mWaveLength + mOffset, mCenterY);
199+
}
200+
if (mWaveFillTop) {
201+
fillTop();
202+
}
203+
204+
canvas.drawPath(mWavePath, mWavePaint);
205+
}
206+
207+
208+
/**
209+
* 填充波浪上面部分
210+
*/
211+
private void fillTop() {
212+
mWavePath.lineTo(mScreenWidth, 0);
213+
mWavePath.lineTo(0, 0);
214+
mWavePath.close();
215+
61216
}
62217

218+
/**
219+
* 填充波浪下面部分
220+
*/
221+
private void fillBottom() {
222+
//填充矩形
223+
mWavePath.lineTo(mScreenWidth, mScreenHeight);
224+
mWavePath.lineTo(0, mScreenHeight);
225+
mWavePath.close();
226+
227+
}
228+
229+
private void Animation() {
230+
231+
ValueAnimator waveAnimator = ValueAnimator.ofInt(0, mWaveLength);
232+
waveAnimator.setDuration(mWaveDuration);
233+
waveAnimator.setRepeatCount(ValueAnimator.INFINITE);
234+
waveAnimator.setInterpolator(new LinearInterpolator());
235+
waveAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
236+
@Override
237+
public void onAnimationUpdate(ValueAnimator animation) {
238+
mOffset = (int) animation.getAnimatedValue();
239+
invalidate();
240+
}
241+
});
242+
waveAnimator.start();
243+
}
244+
245+
/**
246+
* 单位转换工具类
247+
*
248+
* @param context 上下文对象
249+
* @param dipValue 值
250+
* @return 返回值
251+
*/
252+
public int dip2px(Context context, float dipValue) {
253+
final float scale = context.getResources().getDisplayMetrics().density;
254+
return (int) (dipValue * scale + 0.5f);
255+
}
63256

64257
}

0 commit comments

Comments
 (0)