8
8
import android .graphics .drawable .TransitionDrawable ;
9
9
import android .os .Build ;
10
10
import android .os .Handler ;
11
+ import android .os .Message ;
11
12
import android .renderscript .RSRuntimeException ;
12
13
import android .support .annotation .Nullable ;
13
14
import android .support .v4 .view .ViewPager ;
32
33
public class ECardFlowLayout extends FrameLayout {
33
34
34
35
private static final int SWITCH_ANIM_TIME = 300 ;
36
+ private static final int MSG_JUDGE_RESET = 100 ;
35
37
36
38
private Context mContext ;
37
39
private ExecutorService mThreadPool ;
@@ -124,11 +126,18 @@ public void onPageScrollStateChanged(int state) {
124
126
}
125
127
126
128
private void init () {
127
-
128
129
mThreadPool = Executors .newCachedThreadPool ();
129
- mHandler = new Handler ();
130
130
mNotifyRunnable = new NotifyRunnable ();
131
-
131
+ mHandler = new Handler (new Handler .Callback () {
132
+ @ Override
133
+ public boolean handleMessage (Message msg ) {
134
+ if (msg .arg1 == MSG_JUDGE_RESET ) {
135
+ judgeReset ();
136
+ return true ;
137
+ }
138
+ return false ;
139
+ }
140
+ });
132
141
mBlurImage = new ImageView (mContext );
133
142
initImageView (mBlurImage );
134
143
mBgImage = new ImageView (mContext );
@@ -146,26 +155,24 @@ private void updateNextRes(final int position) {
146
155
recycleBitmap (lastBp );
147
156
lastBp = curBp ;
148
157
curBp = nextBp ;
149
- if (mProvider != null ) {
150
- mThreadPool .execute (new Runnable () {
151
- @ Override
152
- public void run () {
153
- nextBp = mProvider .onProvider (position + 1 );
154
- }
155
- });
156
- } else {
157
- throw new RuntimeException ("setImageProvider is necessary" );
158
- }
159
158
if (mBlurImage != null ) {
160
159
recycleBitmap (lastBlurBp );
161
160
lastBlurBp = curBlurBp ;
162
161
curBlurBp = nextBlurBp ;
162
+ }
163
+ if (mProvider != null ) {
163
164
mThreadPool .execute (new Runnable () {
164
165
@ Override
165
166
public void run () {
166
- nextBlurBp = blurBitmap (mProvider .onProvider (position + 1 ));
167
+ nextBp = mProvider .onProvider (position + 1 );
168
+ if (mBlurImage != null ) {
169
+ nextBlurBp = blurBitmap (mProvider .onProvider (position + 1 ));
170
+ }
171
+ sendMsg ();
167
172
}
168
173
});
174
+ } else {
175
+ throw new RuntimeException ("setImageProvider is necessary" );
169
176
}
170
177
}
171
178
@@ -174,45 +181,45 @@ private void updateLastRes(final int position) {
174
181
recycleBitmap (nextBp );
175
182
nextBp = curBp ;
176
183
curBp = lastBp ;
177
- if (mProvider != null ) {
178
- mThreadPool .execute (new Runnable () {
179
- @ Override
180
- public void run () {
181
- lastBp = mProvider .onProvider (position - 1 );
182
- }
183
- });
184
- } else {
185
- throw new RuntimeException ("setImageProvider is necessary" );
186
- }
187
184
if (mBlurImage != null ) {
188
185
recycleBitmap (nextBlurBp );
189
186
nextBlurBp = curBlurBp ;
190
187
curBlurBp = lastBlurBp ;
188
+ }
189
+ if (mProvider != null ) {
191
190
mThreadPool .execute (new Runnable () {
192
191
@ Override
193
192
public void run () {
194
- lastBlurBp = blurBitmap (mProvider .onProvider (position - 1 ));
193
+ lastBp = mProvider .onProvider (position - 1 );
194
+ if (mBlurImage != null ) {
195
+ lastBlurBp = blurBitmap (mProvider .onProvider (position - 1 ));
196
+ }
197
+ sendMsg ();
195
198
}
196
199
});
200
+ } else {
201
+ throw new RuntimeException ("setImageProvider is necessary" );
197
202
}
198
203
}
199
204
205
+ private void startTrans (int targetPosition , ImageView targetImage , Bitmap startBp , Bitmap endBp ) {
206
+ if (endBp == null )
207
+ endBp = mProvider .onProvider (targetPosition );
208
+ TransitionDrawable td = new TransitionDrawable (new Drawable [] {new BitmapDrawable (mContext .getResources (), startBp ),
209
+ new BitmapDrawable (mContext .getResources (), endBp )});
210
+ targetImage .setImageDrawable (td );
211
+ td .setCrossFadeEnabled (true );
212
+ td .startTransition (mSwitchAnimTime );
213
+ }
214
+
200
215
private void switchBgToNext (final int targetPosition ) {
201
216
if (isSwitching ) {
202
217
return ;
203
218
}
204
219
isSwitching = true ;
205
- TransitionDrawable td = new TransitionDrawable (new Drawable [] {new BitmapDrawable (mContext .getResources (), curBp ),
206
- new BitmapDrawable (mContext .getResources (), nextBp )});
207
- mBgImage .setImageDrawable (td );
208
- td .setCrossFadeEnabled (true );
209
- td .startTransition (mSwitchAnimTime );
220
+ startTrans (targetPosition + 1 , mBgImage , curBp , nextBp );
210
221
if (mBlurImage != null ) {
211
- TransitionDrawable tdb = new TransitionDrawable (new Drawable [] {new BitmapDrawable (mContext .getResources (), curBlurBp ),
212
- new BitmapDrawable (mContext .getResources (), nextBlurBp )});
213
- mBlurImage .setImageDrawable (tdb );
214
- tdb .setCrossFadeEnabled (true );
215
- tdb .startTransition (mSwitchAnimTime );
222
+ startTrans (targetPosition + 1 , mBlurImage , curBlurBp , nextBlurBp );
216
223
}
217
224
mNotifyRunnable .setTarget (targetPosition , true );
218
225
mBgImage .postDelayed (mNotifyRunnable , mSwitchAnimTime );
@@ -223,20 +230,58 @@ private void switchBgToLast(final int targetPosition) {
223
230
return ;
224
231
}
225
232
isSwitching = true ;
233
+ startTrans (targetPosition - 1 , mBgImage , curBp , lastBp );
234
+ if (mBlurImage != null ) {
235
+ startTrans (targetPosition - 1 , mBlurImage , curBlurBp , lastBlurBp );
236
+ }
237
+ mNotifyRunnable .setTarget (targetPosition , false );
238
+ mBgImage .postDelayed (mNotifyRunnable , mSwitchAnimTime );
239
+ }
240
+
241
+ private void jumpBgToTarget (final int targetPosition ) {
242
+ mCurPosition = targetPosition ;
243
+ if (isSwitching ) {
244
+ return ;
245
+ }
246
+ isSwitching = true ;
247
+ final Bitmap newBitmap = mProvider .onProvider (targetPosition );
226
248
TransitionDrawable td = new TransitionDrawable (new Drawable [] {new BitmapDrawable (mContext .getResources (), curBp ),
227
- new BitmapDrawable (mContext .getResources (), lastBp )});
249
+ new BitmapDrawable (mContext .getResources (), newBitmap )});
228
250
mBgImage .setImageDrawable (td );
229
251
td .setCrossFadeEnabled (true );
230
252
td .startTransition (mSwitchAnimTime );
231
253
if (mBlurImage != null ) {
232
254
TransitionDrawable tdb = new TransitionDrawable (new Drawable [] {new BitmapDrawable (mContext .getResources (), curBlurBp ),
233
- new BitmapDrawable (mContext .getResources (), lastBlurBp )});
255
+ new BitmapDrawable (mContext .getResources (), blurBitmap ( mProvider . onProvider ( targetPosition )) )});
234
256
mBlurImage .setImageDrawable (tdb );
235
257
tdb .setCrossFadeEnabled (true );
236
258
tdb .startTransition (mSwitchAnimTime );
237
259
}
238
- mNotifyRunnable .setTarget (targetPosition , false );
239
- mBgImage .postDelayed (mNotifyRunnable , mSwitchAnimTime );
260
+ mBgImage .postDelayed (new Runnable () {
261
+ @ Override
262
+ public void run () {
263
+ mThreadPool .execute (new Runnable () {
264
+ @ Override
265
+ public void run () {
266
+ recycleBitmap (nextBp );
267
+ recycleBitmap (lastBp );
268
+ recycleBitmap (curBp );
269
+ curBp = newBitmap ;
270
+ nextBp = mProvider .onProvider (targetPosition + 1 );
271
+ lastBp = mProvider .onProvider (targetPosition - 1 );
272
+ if (mBlurImage != null ) {
273
+ recycleBitmap (nextBlurBp );
274
+ recycleBitmap (lastBlurBp );
275
+ recycleBitmap (curBlurBp );
276
+ curBlurBp = blurBitmap (mProvider .onProvider (targetPosition ));
277
+ nextBlurBp = blurBitmap (mProvider .onProvider (targetPosition + 1 ));
278
+ lastBlurBp = blurBitmap (mProvider .onProvider (targetPosition - 1 ));
279
+ }
280
+ sendMsg ();
281
+ }
282
+ });
283
+ }
284
+ }, mSwitchAnimTime );
240
285
}
241
286
242
287
private class NotifyRunnable implements Runnable {
@@ -251,21 +296,30 @@ public void run() {
251
296
} else {
252
297
updateLastRes (targetPosition );
253
298
}
254
- isSwitching = false ;
255
- judgeReset ();
256
299
}
257
300
258
- public void setTarget (int targetPosition , boolean isNext ) {
301
+ void setTarget (int targetPosition , boolean isNext ) {
259
302
this .targetPosition = targetPosition ;
260
303
this .isNext = isNext ;
261
304
}
262
305
}
263
306
307
+ private void sendMsg () {
308
+ Message msg = new Message ();
309
+ msg .arg1 = MSG_JUDGE_RESET ;
310
+ mHandler .sendMessage (msg );
311
+ }
312
+
264
313
private void judgeReset () {
265
- if (mCurPosition > mLastPosition ) {
266
- switchBgToLast (mLastPosition );
267
- } else if (mCurPosition < mLastPosition ) {
268
- switchBgToNext (mLastPosition );
314
+ isSwitching = false ;
315
+ if (Math .abs (mCurPosition - mLastPosition ) <= 1 ) {
316
+ if (mCurPosition > mLastPosition ) {
317
+ switchBgToLast (mLastPosition );
318
+ } else if (mCurPosition < mLastPosition ) {
319
+ switchBgToNext (mLastPosition );
320
+ }
321
+ } else {
322
+ jumpBgToTarget (mLastPosition );
269
323
}
270
324
}
271
325
@@ -322,6 +376,10 @@ public void setSwitchAnimTime(int switchAnimTime) {
322
376
}
323
377
324
378
public void onDestroy () {
379
+ mHandler .removeCallbacksAndMessages (null );
380
+ if (!mThreadPool .isShutdown ()) {
381
+ mThreadPool .shutdown ();
382
+ }
325
383
recycleBitmap (curBp );
326
384
recycleBitmap (lastBp );
327
385
recycleBitmap (nextBp );
@@ -330,6 +388,5 @@ public void onDestroy() {
330
388
recycleBitmap (lastBlurBp );
331
389
recycleBitmap (nextBlurBp );
332
390
}
333
- mHandler .removeCallbacks (mNotifyRunnable );
334
391
}
335
- }
392
+ }
0 commit comments