1
1
package moe .codeest .enviews ;
2
2
3
- import android .animation .ValueAnimator ;
4
3
import android .content .Context ;
5
4
import android .graphics .Canvas ;
6
5
import android .graphics .Color ;
7
6
import android .graphics .Paint ;
8
7
import android .graphics .Path ;
8
+ import android .graphics .PixelFormat ;
9
+ import android .graphics .PorterDuffXfermode ;
9
10
import android .util .AttributeSet ;
10
- import android .view .View ;
11
- import android .view .animation . LinearInterpolator ;
11
+ import android .view .SurfaceHolder ;
12
+ import android .view .SurfaceView ;
12
13
13
14
/**
14
15
* Created by codeest on 2016/11/15.
15
16
*
16
17
* 我还在好奇里面装的究竟是啤酒还是橙汁 0v0
17
18
*/
18
19
19
- public class ENLoadingView extends View {
20
+ public class ENLoadingView extends SurfaceView {
20
21
21
22
private static final int STATE_SHOW = 0 ;
22
23
23
24
private static final int STATE_HIDE = 1 ;
24
25
25
26
private static final int DEFAULT_RIPPLE_SPEED = 2 ;
26
27
28
+ private static final float DEFAULT_MOVE_SPEED = 0.01f ;
29
+
27
30
private Paint mPaint [], mBeerPaint [], mBubblePaint [];
28
31
29
32
private Path mPath , mBgPath ;
30
33
31
- private ValueAnimator valueAnim ;
34
+ private Thread mThread ;
32
35
33
36
private boolean isItemReady [];
34
37
38
+ private float mCurrentRippleX [];
39
+
35
40
private float mFraction [];
36
41
42
+ private float mTemp = 0 ;
43
+
37
44
private int mCurrentState ;
38
45
39
46
private float mWidth , mHeight ;
40
47
41
48
private float mCenterX , mCenterY ;
42
49
43
- private float mBaseLength ;
44
- private float mBgBaseLength ;
45
- private float mCurrentRippleX [] ;
50
+ private SurfaceHolder surfaceHolder ;
51
+
52
+ private float mBaseLength , mBgBaseLength ;
46
53
47
54
public ENLoadingView (Context context ) {
48
55
super (context );
56
+ init ();
49
57
}
50
58
51
59
public ENLoadingView (Context context , AttributeSet attrs ) {
52
60
super (context , attrs );
61
+ init ();
62
+ }
63
+
64
+ private void init () {
53
65
mPaint = new Paint [4 ];
54
66
mBeerPaint = new Paint [4 ];
55
67
mBubblePaint = new Paint [4 ];
@@ -58,6 +70,7 @@ public ENLoadingView(Context context, AttributeSet attrs) {
58
70
isItemReady = new boolean [4 ];
59
71
mFraction = new float [4 ];
60
72
mCurrentRippleX = new float [4 ];
73
+ mCurrentState = STATE_HIDE ;
61
74
62
75
for (int i = 0 ; i < 4 ; i ++) {
63
76
mPaint [i ] = new Paint (Paint .ANTI_ALIAS_FLAG );
@@ -75,29 +88,28 @@ public ENLoadingView(Context context, AttributeSet attrs) {
75
88
mBubblePaint [i ].setStyle (Paint .Style .FILL );
76
89
mBubblePaint [i ].setColor (Color .parseColor ("#f5fba1" ));
77
90
}
91
+ surfaceHolder = getHolder ();
92
+ setZOrderOnTop (true );
93
+ surfaceHolder .setFormat (PixelFormat .TRANSLUCENT );
94
+ surfaceHolder .addCallback (new SurfaceHolder .Callback () {
95
+ @ Override
96
+ public void surfaceCreated (SurfaceHolder surfaceHolder ) {
97
+
98
+ }
99
+
100
+ @ Override
101
+ public void surfaceChanged (SurfaceHolder surfaceHolder , int i , int i1 , int i2 ) {
102
+
103
+ }
78
104
79
- valueAnim = ValueAnimator .ofFloat (1.f , 100.f );
80
- valueAnim .setDuration (3000 );
81
- valueAnim .setInterpolator (new LinearInterpolator ());
82
- valueAnim .setRepeatCount (ValueAnimator .INFINITE );
83
- valueAnim .setRepeatMode (ValueAnimator .RESTART );
84
- valueAnim .addUpdateListener (new ValueAnimator .AnimatorUpdateListener () {
85
105
@ Override
86
- public void onAnimationUpdate (ValueAnimator valueAnimator ) {
87
- for (int i = 0 ;i < 4 ; i ++) {
88
- float temp = valueAnimator .getAnimatedFraction () - i * 0.25f ;
89
- if (temp < 0 )
90
- temp += 1 ;
91
- mFraction [i ] = temp ;
92
- if (mFraction [0 ] > i * 0.25f && !isItemReady [i ]) {
93
- isItemReady [i ] = true ;
94
- }
106
+ public void surfaceDestroyed (SurfaceHolder surfaceHolder ) {
107
+ if (mThread != null ) {
108
+ mThread .interrupt ();
109
+ mThread = null ;
95
110
}
96
- invalidate ();
97
111
}
98
112
});
99
-
100
- mCurrentState = STATE_HIDE ;
101
113
}
102
114
103
115
@ Override
@@ -123,16 +135,52 @@ protected void onSizeChanged(int w, int h, int oldw, int oldh) {
123
135
mPath .lineTo (mBaseLength , mCenterY );
124
136
mPath .lineTo (mBaseLength , mCenterY + 2 * mBaseLength );
125
137
mPath .close ();
138
+ }
139
+
140
+ private Runnable animRunnable = new Runnable () {
141
+ @ Override
142
+ public void run () {
143
+ try {
144
+ while (mCurrentState == STATE_SHOW ) {
145
+ Thread .sleep (5 );
146
+ flush ();
147
+ draw ();
148
+ }
149
+ if (mCurrentState == STATE_HIDE ) {
150
+ clearCanvas ();
151
+ }
152
+ } catch (InterruptedException e ) {
153
+ e .printStackTrace ();
154
+ }
155
+ }
156
+ };
126
157
127
- setAlpha (0 );
158
+ private void flush () {
159
+ if (mTemp >= 1 )
160
+ mTemp = 0 ;
161
+ mTemp += DEFAULT_MOVE_SPEED ;
162
+ for (int i = 0 ;i < 4 ; i ++) {
163
+ float temp = mTemp - i * 0.25f ;
164
+ if (temp < 0 )
165
+ temp += 1 ;
166
+ mFraction [i ] = temp ;
167
+ if (mFraction [0 ] > i * 0.25f && !isItemReady [i ]) {
168
+ isItemReady [i ] = true ;
169
+ }
170
+ }
128
171
}
129
172
130
- @ Override
131
- protected void onDraw (Canvas canvas ) {
132
- super .onDraw (canvas );
173
+ private void draw () {
174
+ Canvas canvas = surfaceHolder .lockCanvas ();
175
+ if (canvas == null )
176
+ return ;
177
+ mPaint [0 ].setXfermode (new PorterDuffXfermode (android .graphics .PorterDuff .Mode .CLEAR )); //使用这只画笔清屏,清屏后恢复画笔
178
+ canvas .drawPaint (mPaint [0 ]);
179
+ mPaint [0 ].setXfermode (new PorterDuffXfermode (android .graphics .PorterDuff .Mode .DST_OVER ));
133
180
for (int i = 0 ; i < 4 ; i ++) {
134
181
drawItem (canvas , mFraction [i ], i );
135
182
}
183
+ surfaceHolder .unlockCanvasAndPost (canvas );
136
184
}
137
185
138
186
private void drawItem (Canvas canvas , float mFraction , int index ) {
@@ -198,24 +246,35 @@ public void show() {
198
246
return ;
199
247
}
200
248
mCurrentState = STATE_SHOW ;
201
- this . animate (). alpha ( 1 ). setDuration ( 200 ). start ( );
202
- valueAnim .start ();
249
+ mThread = new Thread ( animRunnable );
250
+ mThread .start ();
203
251
}
204
252
205
253
public void hide () {
206
254
if (mCurrentState == STATE_HIDE ) {
207
255
return ;
208
256
}
209
257
mCurrentState = STATE_HIDE ;
210
- this .animate ().alpha (0 ).setDuration (200 ).start ();
211
- valueAnim .cancel ();
212
258
resetData ();
213
259
}
214
260
261
+ private void clearCanvas () {
262
+ Canvas canvas = surfaceHolder .lockCanvas ();
263
+ if (canvas == null )
264
+ return ;
265
+ mPaint [0 ].setXfermode (new PorterDuffXfermode (android .graphics .PorterDuff .Mode .CLEAR ));
266
+ canvas .drawPaint (mPaint [0 ]);
267
+ mPaint [0 ].setXfermode (new PorterDuffXfermode (android .graphics .PorterDuff .Mode .DST_OVER ));
268
+ surfaceHolder .unlockCanvasAndPost (canvas );
269
+ mThread .interrupt ();
270
+ mThread = null ;
271
+ }
272
+
215
273
private void resetData () {
216
274
for (int i = 0 ; i <4 ; i ++) {
217
275
isItemReady [i ] = false ;
218
276
mCurrentRippleX [i ] = - 2 * mBgBaseLength ;
219
277
}
278
+ mTemp = 0 ;
220
279
}
221
280
}
0 commit comments