88import android .graphics .drawable .TransitionDrawable ;
99import android .os .Build ;
1010import android .os .Handler ;
11+ import android .os .Message ;
1112import android .renderscript .RSRuntimeException ;
1213import android .support .annotation .Nullable ;
1314import android .support .v4 .view .ViewPager ;
3233public class ECardFlowLayout extends FrameLayout {
3334
3435 private static final int SWITCH_ANIM_TIME = 300 ;
36+ private static final int MSG_JUDGE_RESET = 100 ;
3537
3638 private Context mContext ;
3739 private ExecutorService mThreadPool ;
@@ -124,11 +126,18 @@ public void onPageScrollStateChanged(int state) {
124126 }
125127
126128 private void init () {
127-
128129 mThreadPool = Executors .newCachedThreadPool ();
129- mHandler = new Handler ();
130130 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+ });
132141 mBlurImage = new ImageView (mContext );
133142 initImageView (mBlurImage );
134143 mBgImage = new ImageView (mContext );
@@ -146,26 +155,24 @@ private void updateNextRes(final int position) {
146155 recycleBitmap (lastBp );
147156 lastBp = curBp ;
148157 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- }
159158 if (mBlurImage != null ) {
160159 recycleBitmap (lastBlurBp );
161160 lastBlurBp = curBlurBp ;
162161 curBlurBp = nextBlurBp ;
162+ }
163+ if (mProvider != null ) {
163164 mThreadPool .execute (new Runnable () {
164165 @ Override
165166 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 ();
167172 }
168173 });
174+ } else {
175+ throw new RuntimeException ("setImageProvider is necessary" );
169176 }
170177 }
171178
@@ -174,45 +181,45 @@ private void updateLastRes(final int position) {
174181 recycleBitmap (nextBp );
175182 nextBp = curBp ;
176183 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- }
187184 if (mBlurImage != null ) {
188185 recycleBitmap (nextBlurBp );
189186 nextBlurBp = curBlurBp ;
190187 curBlurBp = lastBlurBp ;
188+ }
189+ if (mProvider != null ) {
191190 mThreadPool .execute (new Runnable () {
192191 @ Override
193192 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 ();
195198 }
196199 });
200+ } else {
201+ throw new RuntimeException ("setImageProvider is necessary" );
197202 }
198203 }
199204
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+
200215 private void switchBgToNext (final int targetPosition ) {
201216 if (isSwitching ) {
202217 return ;
203218 }
204219 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 );
210221 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 );
216223 }
217224 mNotifyRunnable .setTarget (targetPosition , true );
218225 mBgImage .postDelayed (mNotifyRunnable , mSwitchAnimTime );
@@ -223,20 +230,58 @@ private void switchBgToLast(final int targetPosition) {
223230 return ;
224231 }
225232 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 );
226248 TransitionDrawable td = new TransitionDrawable (new Drawable [] {new BitmapDrawable (mContext .getResources (), curBp ),
227- new BitmapDrawable (mContext .getResources (), lastBp )});
249+ new BitmapDrawable (mContext .getResources (), newBitmap )});
228250 mBgImage .setImageDrawable (td );
229251 td .setCrossFadeEnabled (true );
230252 td .startTransition (mSwitchAnimTime );
231253 if (mBlurImage != null ) {
232254 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 )) )});
234256 mBlurImage .setImageDrawable (tdb );
235257 tdb .setCrossFadeEnabled (true );
236258 tdb .startTransition (mSwitchAnimTime );
237259 }
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 );
240285 }
241286
242287 private class NotifyRunnable implements Runnable {
@@ -251,21 +296,30 @@ public void run() {
251296 } else {
252297 updateLastRes (targetPosition );
253298 }
254- isSwitching = false ;
255- judgeReset ();
256299 }
257300
258- public void setTarget (int targetPosition , boolean isNext ) {
301+ void setTarget (int targetPosition , boolean isNext ) {
259302 this .targetPosition = targetPosition ;
260303 this .isNext = isNext ;
261304 }
262305 }
263306
307+ private void sendMsg () {
308+ Message msg = new Message ();
309+ msg .arg1 = MSG_JUDGE_RESET ;
310+ mHandler .sendMessage (msg );
311+ }
312+
264313 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 );
269323 }
270324 }
271325
@@ -322,6 +376,10 @@ public void setSwitchAnimTime(int switchAnimTime) {
322376 }
323377
324378 public void onDestroy () {
379+ mHandler .removeCallbacksAndMessages (null );
380+ if (!mThreadPool .isShutdown ()) {
381+ mThreadPool .shutdown ();
382+ }
325383 recycleBitmap (curBp );
326384 recycleBitmap (lastBp );
327385 recycleBitmap (nextBp );
@@ -330,6 +388,5 @@ public void onDestroy() {
330388 recycleBitmap (lastBlurBp );
331389 recycleBitmap (nextBlurBp );
332390 }
333- mHandler .removeCallbacks (mNotifyRunnable );
334391 }
335- }
392+ }
0 commit comments