Skip to content

Commit f176922

Browse files
committed
add LruCache
1 parent d5e5d25 commit f176922

File tree

5 files changed

+171
-42
lines changed

5 files changed

+171
-42
lines changed

app/src/main/java/moe/codeest/ecardflowdemo/activity/CardFlowActivity.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,4 +70,13 @@ public void onClick(View v) {
7070
public void onShrink() {
7171
mEcardflow.shrink();
7272
}
73+
74+
@Override
75+
public void onBackPressed() {
76+
if (mEcardflow.isExpanding()) {
77+
mEcardflow.shrink();
78+
} else {
79+
super.onBackPressed();
80+
}
81+
}
7382
}

ecardflow/src/main/java/moe/codeest/ecardflow/ECardFlow.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616

1717
import java.lang.reflect.Field;
1818

19+
import moe.codeest.ecardflow.support.CardFlowTransformer;
1920
import moe.codeest.ecardflow.util.DimenUtils;
2021

2122
/**
@@ -169,6 +170,10 @@ public void setTouchSlop(int slop) {
169170
mSlop = slop;
170171
}
171172

173+
public boolean isExpanding() {
174+
return isExpanding;
175+
}
176+
172177
public void expand() {
173178
isExpanding = true;
174179
View pageView = getPageView();

ecardflow/src/main/java/moe/codeest/ecardflow/ECardFlowLayout.java

Lines changed: 98 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,10 @@
1111
import android.os.Message;
1212
import android.renderscript.RSRuntimeException;
1313
import android.support.annotation.Nullable;
14+
import android.support.v4.util.LruCache;
1415
import android.support.v4.view.ViewPager;
1516
import android.util.AttributeSet;
17+
import android.util.Log;
1618
import android.view.ViewGroup;
1719
import android.widget.FrameLayout;
1820
import android.widget.ImageView;
@@ -24,6 +26,7 @@
2426
import moe.codeest.ecardflow.mode.AnimMode;
2527
import moe.codeest.ecardflow.mode.BlurAnimMode;
2628
import moe.codeest.ecardflow.provider.ImageProvider;
29+
import moe.codeest.ecardflow.support.RecyclingBitmapDrawable;
2730
import moe.codeest.ecardflow.util.FastBlur;
2831
import moe.codeest.ecardflow.util.RSBlur;
2932

@@ -33,11 +36,12 @@
3336

3437
public class ECardFlowLayout extends FrameLayout{
3538

36-
private static final int SWITCH_ANIM_TIME = 300;
39+
private static final int SWITCH_ANIM_TIME = 300; //300 ms
3740
private static final int MSG_JUDGE_RESET = 0x1;
3841

3942
private Context mContext;
4043
private ExecutorService mThreadPool;
44+
private LruCache<String, RecyclingBitmapDrawable> mLruCache;
4145
private MyHandler mHandler;
4246
private NotifyRunnable mNotifyRunnable;
4347

@@ -48,11 +52,12 @@ public class ECardFlowLayout extends FrameLayout{
4852
private ImageProvider mProvider;
4953
private AnimMode mAnimMode;
5054

51-
private Bitmap curBp, lastBp, nextBp;
55+
private RecyclingBitmapDrawable curBp, lastBp, nextBp;
5256
private Bitmap curBlurBp, lastBlurBp, nextBlurBp;
5357

5458
private int mCurDirection = AnimMode.D_RIGHT;
5559
private int mSwitchAnimTime = SWITCH_ANIM_TIME;
60+
private int mMinCacheSize;
5661
private float mLastOffset;
5762
private int mRadius;
5863
private int mCurPosition;
@@ -84,6 +89,7 @@ private void init() {
8489
mThreadPool = Executors.newCachedThreadPool();
8590
mNotifyRunnable = new NotifyRunnable();
8691
mHandler = new MyHandler(this);
92+
initCache();
8793
mBlurImage = new ImageView(mContext);
8894
initImageView(mBlurImage);
8995
mBgImage = new ImageView(mContext);
@@ -142,9 +148,38 @@ public void onPageScrollStateChanged(int state) {
142148
});
143149
}
144150

151+
private void initCache() {
152+
int maxMemory = (int) Runtime.getRuntime().maxMemory() / 1024;
153+
int cacheSize = maxMemory / 5;
154+
mMinCacheSize = maxMemory / 8;
155+
mLruCache = new LruCache<String, RecyclingBitmapDrawable>(cacheSize) {
156+
@Override
157+
protected int sizeOf(String key, RecyclingBitmapDrawable value) {
158+
return value.getBitmap().getByteCount() / 1024;
159+
}
160+
161+
@Override
162+
protected void entryRemoved(boolean evicted, String key, RecyclingBitmapDrawable oldValue, RecyclingBitmapDrawable newValue) {
163+
super.entryRemoved(evicted, key, oldValue, newValue);
164+
if (evicted && oldValue != null) {
165+
oldValue.setIsCached(false);
166+
}
167+
}
168+
169+
@Override
170+
protected RecyclingBitmapDrawable create(String key) {
171+
RecyclingBitmapDrawable bitmap = new RecyclingBitmapDrawable(getResources(), mProvider.onProvider(Integer.valueOf(key)));
172+
if (bitmap.getBitmap() == null)
173+
return null;
174+
bitmap.setIsCached(true);
175+
return bitmap;
176+
}
177+
};
178+
}
179+
145180
private void updateNextRes(final int position) {
146181
mCurPosition = position;
147-
recycleBitmap(lastBp);
182+
detachBitmap(lastBp);
148183
lastBp = curBp;
149184
curBp = nextBp;
150185
if (mBlurImage != null) {
@@ -156,9 +191,9 @@ private void updateNextRes(final int position) {
156191
mThreadPool.execute(new Runnable() {
157192
@Override
158193
public void run() {
159-
nextBp = mProvider.onProvider(position + 1);
194+
nextBp = loadBitmap(position + 1);
160195
if (mBlurImage != null) {
161-
nextBlurBp = blurBitmap(mProvider.onProvider(position + 1));
196+
nextBlurBp = blurBitmap(position + 1);
162197
}
163198
sendMsg();
164199
}
@@ -170,7 +205,7 @@ public void run() {
170205

171206
private void updateLastRes(final int position) {
172207
mCurPosition = position;
173-
recycleBitmap(nextBp);
208+
detachBitmap(nextBp);
174209
nextBp = curBp;
175210
curBp = lastBp;
176211
if (mBlurImage != null) {
@@ -182,9 +217,9 @@ private void updateLastRes(final int position) {
182217
mThreadPool.execute(new Runnable() {
183218
@Override
184219
public void run() {
185-
lastBp = mProvider.onProvider(position - 1);
220+
lastBp = loadBitmap(position - 1);
186221
if (mBlurImage != null) {
187-
lastBlurBp = blurBitmap(mProvider.onProvider(position - 1));
222+
lastBlurBp = blurBitmap(position - 1);
188223
}
189224
sendMsg();
190225
}
@@ -194,11 +229,10 @@ public void run() {
194229
}
195230
}
196231

197-
private void startTrans(int targetPosition, ImageView targetImage, Bitmap startBp, Bitmap endBp) {
232+
private void startTrans(int targetPosition, ImageView targetImage, RecyclingBitmapDrawable startBp, RecyclingBitmapDrawable endBp) {
198233
if (endBp == null)
199-
endBp = mProvider.onProvider(targetPosition);
200-
TransitionDrawable td = new TransitionDrawable(new Drawable[] {new BitmapDrawable(mContext.getResources(), startBp),
201-
new BitmapDrawable(mContext.getResources(), endBp)});
234+
endBp = loadBitmap(targetPosition);
235+
TransitionDrawable td = new TransitionDrawable(new Drawable[] {startBp, endBp});
202236
targetImage.setImageDrawable(td);
203237
td.setCrossFadeEnabled(true);
204238
td.startTransition(mSwitchAnimTime);
@@ -211,7 +245,7 @@ private void switchBgToNext(final int targetPosition) {
211245
isSwitching = true;
212246
startTrans(targetPosition + 1, mBgImage, curBp, nextBp);
213247
if (mBlurImage != null) {
214-
startTrans(targetPosition + 1, mBlurImage, curBlurBp, nextBlurBp);
248+
startTrans(targetPosition + 1, mBlurImage, new RecyclingBitmapDrawable(getResources(), curBlurBp), new RecyclingBitmapDrawable(getResources(), nextBlurBp));
215249
}
216250
mNotifyRunnable.setTarget(targetPosition, true);
217251
mBgImage.postDelayed(mNotifyRunnable, mSwitchAnimTime);
@@ -224,7 +258,7 @@ private void switchBgToLast(final int targetPosition) {
224258
isSwitching = true;
225259
startTrans(targetPosition - 1, mBgImage, curBp, lastBp);
226260
if (mBlurImage != null) {
227-
startTrans(targetPosition - 1, mBlurImage, curBlurBp, lastBlurBp);
261+
startTrans(targetPosition - 1, mBlurImage, new RecyclingBitmapDrawable(getResources(), curBlurBp), new RecyclingBitmapDrawable(getResources(), lastBlurBp));
228262
}
229263
mNotifyRunnable.setTarget(targetPosition, false);
230264
mBgImage.postDelayed(mNotifyRunnable, mSwitchAnimTime);
@@ -236,15 +270,14 @@ private void jumpBgToTarget(final int targetPosition) {
236270
return;
237271
}
238272
isSwitching = true;
239-
final Bitmap newBitmap = mProvider.onProvider(targetPosition);
240-
TransitionDrawable td = new TransitionDrawable(new Drawable[] {new BitmapDrawable(mContext.getResources(), curBp),
241-
new BitmapDrawable(mContext.getResources(), newBitmap)});
273+
final RecyclingBitmapDrawable newBitmap = loadBitmap(targetPosition);
274+
TransitionDrawable td = new TransitionDrawable(new Drawable[] {curBp, newBitmap});
242275
mBgImage.setImageDrawable(td);
243276
td.setCrossFadeEnabled(true);
244277
td.startTransition(mSwitchAnimTime);
245278
if (mBlurImage != null) {
246279
TransitionDrawable tdb = new TransitionDrawable(new Drawable[] {new BitmapDrawable(mContext.getResources(), curBlurBp),
247-
new BitmapDrawable(mContext.getResources(), blurBitmap(mProvider.onProvider(targetPosition)))});
280+
new BitmapDrawable(mContext.getResources(), blurBitmap(targetPosition))});
248281
mBlurImage.setImageDrawable(tdb);
249282
tdb.setCrossFadeEnabled(true);
250283
tdb.startTransition(mSwitchAnimTime);
@@ -255,19 +288,19 @@ public void run() {
255288
mThreadPool.execute(new Runnable() {
256289
@Override
257290
public void run() {
258-
recycleBitmap(nextBp);
259-
recycleBitmap(lastBp);
260-
recycleBitmap(curBp);
291+
detachBitmap(nextBp);
292+
detachBitmap(lastBp);
293+
detachBitmap(curBp);
261294
curBp = newBitmap;
262-
nextBp = mProvider.onProvider(targetPosition + 1);
263-
lastBp = mProvider.onProvider(targetPosition - 1);
295+
nextBp = loadBitmap(targetPosition + 1);
296+
lastBp = loadBitmap(targetPosition - 1);
264297
if (mBlurImage != null) {
265298
recycleBitmap(nextBlurBp);
266299
recycleBitmap(lastBlurBp);
267300
recycleBitmap(curBlurBp);
268-
curBlurBp = blurBitmap(mProvider.onProvider(targetPosition));
269-
nextBlurBp = blurBitmap(mProvider.onProvider(targetPosition + 1));
270-
lastBlurBp = blurBitmap(mProvider.onProvider(targetPosition - 1));
301+
curBlurBp = blurBitmap(targetPosition);
302+
nextBlurBp = blurBitmap(targetPosition + 1);
303+
lastBlurBp = blurBitmap(targetPosition - 1);
271304
}
272305
sendMsg();
273306
}
@@ -298,41 +331,56 @@ private void judgeReset() {
298331
}
299332

300333
@Nullable
301-
private Bitmap blurBitmap(Bitmap bitmap) {
302-
if (bitmap == null) {
334+
private Bitmap blurBitmap(int targetPosition) {
335+
RecyclingBitmapDrawable bitmapDrawable = mLruCache.get(String.valueOf(targetPosition));
336+
if (bitmapDrawable == null || bitmapDrawable.getBitmap() == null) {
303337
return null;
304338
}
305-
Bitmap blurBitmap;
339+
Bitmap blurBitmap = bitmapDrawable.getBitmap().copy(Bitmap.Config.ARGB_8888, true);
306340
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) {
307341
try {
308-
blurBitmap = RSBlur.blur(mContext, bitmap, mRadius);
342+
blurBitmap = RSBlur.blur(mContext, blurBitmap, mRadius);
309343
} catch (RSRuntimeException e) {
310-
blurBitmap = FastBlur.blur(bitmap, mRadius, true);
344+
blurBitmap = FastBlur.blur(blurBitmap, mRadius, true);
311345
}
312346
} else {
313-
blurBitmap = FastBlur.blur(bitmap, mRadius, true);
347+
blurBitmap = FastBlur.blur(blurBitmap, mRadius, true);
314348
}
315349
return blurBitmap;
316350
}
317351

352+
private RecyclingBitmapDrawable loadBitmap(int targetPosition) {
353+
RecyclingBitmapDrawable bitmap = mLruCache.get(String.valueOf(targetPosition));
354+
if (bitmap != null) {
355+
bitmap.setIsDisplayed(true);
356+
}
357+
return bitmap;
358+
}
359+
318360
private void recycleBitmap(Bitmap bitmap) {
319361
if (bitmap != null)
320362
bitmap.recycle();
321363
}
322364

365+
private void detachBitmap(RecyclingBitmapDrawable bitmap) {
366+
if (bitmap != null) {
367+
bitmap.setIsDisplayed(false);
368+
}
369+
}
370+
323371
public void setImageProvider(ImageProvider provider) {
324372
mProvider = provider;
325-
curBp = mProvider.onProvider(0);
326-
nextBp = mProvider.onProvider(1);
373+
curBp = loadBitmap(0);
374+
nextBp = loadBitmap(1);
327375
if (mAnimMode == null) {
328376
throw new RuntimeException("You should setAnimMode before setImageProvider");
329377
}
330378
if (mBlurImage != null) {
331-
curBlurBp = blurBitmap(mProvider.onProvider(0));
332-
nextBlurBp = blurBitmap(mProvider.onProvider(1));
333-
mBlurImage.setImageBitmap(blurBitmap(curBlurBp));
379+
curBlurBp = blurBitmap(0);
380+
nextBlurBp = blurBitmap(1);
381+
mBlurImage.setImageBitmap(blurBitmap(0));
334382
}
335-
mBgImage.setImageBitmap(curBp);
383+
mBgImage.setImageBitmap(curBp.getBitmap());
336384
}
337385

338386
public void setAnimMode(AnimMode animMode) {
@@ -349,15 +397,24 @@ public void setSwitchAnimTime(int switchAnimTime) {
349397
mSwitchAnimTime = switchAnimTime;
350398
}
351399

400+
public void setCacheSize(int megabytes) {
401+
if (megabytes * 1024 >= mMinCacheSize) {
402+
mLruCache.resize(megabytes * 1024);
403+
} else {
404+
Log.w(getClass().getName(), "Size is too small to resize");
405+
}
406+
}
407+
352408
public void onDestroy() {
353409
mHandler.removeCallbacksAndMessages(null);
354410
if (!mThreadPool.isShutdown()) {
355411
mThreadPool.shutdown();
356412
}
357413
mHandler = null;
358-
recycleBitmap(curBp);
359-
recycleBitmap(lastBp);
360-
recycleBitmap(nextBp);
414+
detachBitmap(curBp);
415+
detachBitmap(lastBp);
416+
detachBitmap(nextBp);
417+
mLruCache.evictAll();
361418
if (mBlurImage != null) {
362419
recycleBitmap(curBlurBp);
363420
recycleBitmap(lastBlurBp);

ecardflow/src/main/java/moe/codeest/ecardflow/CardFlowTransformer.java renamed to ecardflow/src/main/java/moe/codeest/ecardflow/support/CardFlowTransformer.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
package moe.codeest.ecardflow;
1+
package moe.codeest.ecardflow.support;
22

33
import android.support.v4.view.ViewPager;
44
import android.view.View;

0 commit comments

Comments
 (0)