11package moe .codeest .enviews ;
22
3- import android .animation .ValueAnimator ;
43import android .content .Context ;
54import android .graphics .Canvas ;
65import android .graphics .Color ;
76import android .graphics .Paint ;
87import android .graphics .Path ;
8+ import android .graphics .PixelFormat ;
9+ import android .graphics .PorterDuffXfermode ;
910import android .util .AttributeSet ;
10- import android .view .View ;
11- import android .view .animation . LinearInterpolator ;
11+ import android .view .SurfaceHolder ;
12+ import android .view .SurfaceView ;
1213
1314/**
1415 * Created by codeest on 2016/11/15.
1516 *
1617 * 我还在好奇里面装的究竟是啤酒还是橙汁 0v0
1718 */
1819
19- public class ENLoadingView extends View {
20+ public class ENLoadingView extends SurfaceView {
2021
2122 private static final int STATE_SHOW = 0 ;
2223
2324 private static final int STATE_HIDE = 1 ;
2425
2526 private static final int DEFAULT_RIPPLE_SPEED = 2 ;
2627
28+ private static final float DEFAULT_MOVE_SPEED = 0.01f ;
29+
2730 private Paint mPaint [], mBeerPaint [], mBubblePaint [];
2831
2932 private Path mPath , mBgPath ;
3033
31- private ValueAnimator valueAnim ;
34+ private Thread mThread ;
3235
3336 private boolean isItemReady [];
3437
38+ private float mCurrentRippleX [];
39+
3540 private float mFraction [];
3641
42+ private float mTemp = 0 ;
43+
3744 private int mCurrentState ;
3845
3946 private float mWidth , mHeight ;
4047
4148 private float mCenterX , mCenterY ;
4249
43- private float mBaseLength ;
44- private float mBgBaseLength ;
45- private float mCurrentRippleX [] ;
50+ private SurfaceHolder surfaceHolder ;
51+
52+ private float mBaseLength , mBgBaseLength ;
4653
4754 public ENLoadingView (Context context ) {
4855 super (context );
56+ init ();
4957 }
5058
5159 public ENLoadingView (Context context , AttributeSet attrs ) {
5260 super (context , attrs );
61+ init ();
62+ }
63+
64+ private void init () {
5365 mPaint = new Paint [4 ];
5466 mBeerPaint = new Paint [4 ];
5567 mBubblePaint = new Paint [4 ];
@@ -58,6 +70,7 @@ public ENLoadingView(Context context, AttributeSet attrs) {
5870 isItemReady = new boolean [4 ];
5971 mFraction = new float [4 ];
6072 mCurrentRippleX = new float [4 ];
73+ mCurrentState = STATE_HIDE ;
6174
6275 for (int i = 0 ; i < 4 ; i ++) {
6376 mPaint [i ] = new Paint (Paint .ANTI_ALIAS_FLAG );
@@ -75,29 +88,28 @@ public ENLoadingView(Context context, AttributeSet attrs) {
7588 mBubblePaint [i ].setStyle (Paint .Style .FILL );
7689 mBubblePaint [i ].setColor (Color .parseColor ("#f5fba1" ));
7790 }
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+ }
78104
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 () {
85105 @ 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 ;
95110 }
96- invalidate ();
97111 }
98112 });
99-
100- mCurrentState = STATE_HIDE ;
101113 }
102114
103115 @ Override
@@ -123,16 +135,52 @@ protected void onSizeChanged(int w, int h, int oldw, int oldh) {
123135 mPath .lineTo (mBaseLength , mCenterY );
124136 mPath .lineTo (mBaseLength , mCenterY + 2 * mBaseLength );
125137 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+ };
126157
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+ }
128171 }
129172
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 ));
133180 for (int i = 0 ; i < 4 ; i ++) {
134181 drawItem (canvas , mFraction [i ], i );
135182 }
183+ surfaceHolder .unlockCanvasAndPost (canvas );
136184 }
137185
138186 private void drawItem (Canvas canvas , float mFraction , int index ) {
@@ -198,24 +246,35 @@ public void show() {
198246 return ;
199247 }
200248 mCurrentState = STATE_SHOW ;
201- this . animate (). alpha ( 1 ). setDuration ( 200 ). start ( );
202- valueAnim .start ();
249+ mThread = new Thread ( animRunnable );
250+ mThread .start ();
203251 }
204252
205253 public void hide () {
206254 if (mCurrentState == STATE_HIDE ) {
207255 return ;
208256 }
209257 mCurrentState = STATE_HIDE ;
210- this .animate ().alpha (0 ).setDuration (200 ).start ();
211- valueAnim .cancel ();
212258 resetData ();
213259 }
214260
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+
215273 private void resetData () {
216274 for (int i = 0 ; i <4 ; i ++) {
217275 isItemReady [i ] = false ;
218276 mCurrentRippleX [i ] = - 2 * mBgBaseLength ;
219277 }
278+ mTemp = 0 ;
220279 }
221280}
0 commit comments