首页 > 代码库 > LruCache类的相关知识以及代码实现
LruCache类的相关知识以及代码实现
一.LruCache的简单介绍
- Cache保存一个强引用来限制内容数量,每当Item被访问的时候,此Item就会移动到队列的头部。
- * 当cache已满的时候加入新的item时,在队列尾部的item会被回收。
- * 如果你cache的某个值需要明确释放,重写entryRemoved()
- * 如果key相对应的item丢掉啦,重写create().这简化了调用代码,即使丢失了也总会返回。
- * is limited to 4MiB of bitmaps: 默认cache大小是测量的item的数量,重写sizeof计算不同item的
- * 大小。
二.使用Lrucache来异步加载图片,防止阻塞(缓存图片)
下面是我的一个小程序,使用得到了Lrucache,总共有三个类,代码注释也是很详细的,很适合初学者学习。主要的功能就是形成一个像瀑布的图片墙。
在第三个类中有这个项目的设计思想。大家可以看看,共同进步,谢谢!!!
第一个类
1 package com.pangzaifei.falls; 2 3 import android.app.Activity; 4 import android.os.Bundle; 5 6 /** 7 * 瀑布流 8 * 9 */10 public class Demo extends Activity {11 @Override12 protected void onCreate(Bundle savedInstanceState) {13 super.onCreate(savedInstanceState);14 setContentView(R.layout.activity_demo);15 16 }17 }
第二个类
1 package com.pangzaifei.falls; 2 3 import android.graphics.Bitmap; 4 import android.graphics.BitmapFactory; 5 import android.graphics.BitmapFactory.Options; 6 import android.support.v4.util.LruCache; 7 8 /** 9 * 图片资源 数据源类 10 * 11 */ 12 public class Images { 13 private static Images images; 14 // Cache保存一个强引用来限制内容数量,每当Item被访问的时候,此Item就会移动到队列的头部。 15 // 当cache已满的时候加入新的item时,在队列尾部的item会被回收。 16 // 如果你cache的某个值需要明确释放,重写entryRemoved() 17 // 如果key相对应的item丢掉啦,重写create().这简化了调用代码,即使丢失了也总会返回。 18 // 默认cache大小是测量的item的数量,重写sizeof计算不同item的大小。 19 private LruCache<String, Bitmap> mMemoryCache; 20 21 public Images() { 22 initLrucache();// 初始化lrucache 23 } 24 25 public static Images getInstance() { 26 if (images == null) { 27 images = new Images(); 28 } 29 return images; 30 } 31 32 /** 33 * 初始化lrucache 34 */ 35 private void initLrucache() { 36 // 获取应用程序最大内存 37 long maxSize = Runtime.getRuntime().maxMemory(); 38 // 设置图片缓存大小为程序最大可用内存的1/8. 39 int cacheSize = (int) (maxSize / 8); 40 mMemoryCache = new LruCache<String, Bitmap>(cacheSize); 41 } 42 43 /** 44 * 从LruCache中获取一张图片,如果不存在就返回null 从lrucache中获得key key LruCache的键,传入图片的url地址 45 * return 对应传入的bitmap对象,或者null 46 */ 47 public Bitmap getMemoryCache(String key) { 48 if (mMemoryCache != null) { 49 Bitmap bitmap = mMemoryCache.get(key); 50 if (bitmap != null) { 51 return bitmap; 52 } 53 } 54 return null; 55 } 56 57 /** 58 * 将图片添加到lrucache中 59 * 60 * @param key 61 * LruCache的键,这里传入图片的URL地址 62 * @param bitmap 63 * 这里指的是从网络上下载的bitmap对象。 64 */ 65 public void addBitmapToMemoryCache(String key, Bitmap bitmap) { 66 if (getMemoryCache(key) == null) { 67 mMemoryCache.put(key, bitmap); 68 } 69 } 70 71 public static final String[] imageThumbs = new String[] { 72 "http://img.my.csdn.net/uploads/201309/01/1378037235_3453.jpg", 73 "http://img.my.csdn.net/uploads/201309/01/1378037235_7476.jpg", 74 "http://img.my.csdn.net/uploads/201309/01/1378037235_9280.jpg", 75 "http://img.my.csdn.net/uploads/201309/01/1378037234_3539.jpg", 76 "http://img.my.csdn.net/uploads/201309/01/1378037234_6318.jpg", 77 "http://img.my.csdn.net/uploads/201309/01/1378037194_2965.jpg", 78 "http://img.my.csdn.net/uploads/201309/01/1378037193_1687.jpg", 79 "http://img.my.csdn.net/uploads/201309/01/1378037193_1286.jpg", 80 "http://img.my.csdn.net/uploads/201309/01/1378037192_8379.jpg", 81 "http://img.my.csdn.net/uploads/201309/01/1378037178_9374.jpg", 82 "http://img.my.csdn.net/uploads/201309/01/1378037177_1254.jpg", 83 "http://img.my.csdn.net/uploads/201309/01/1378037177_6203.jpg", 84 "http://img.my.csdn.net/uploads/201309/01/1378037152_6352.jpg", 85 "http://img.my.csdn.net/uploads/201309/01/1378037151_9565.jpg", 86 "http://img.my.csdn.net/uploads/201309/01/1378037151_7904.jpg", 87 "http://img.my.csdn.net/uploads/201309/01/1378037148_7104.jpg", 88 "http://img.my.csdn.net/uploads/201309/01/1378037129_8825.jpg", 89 "http://img.my.csdn.net/uploads/201309/01/1378037128_5291.jpg", 90 "http://img.my.csdn.net/uploads/201309/01/1378037128_3531.jpg", 91 "http://img.my.csdn.net/uploads/201309/01/1378037127_1085.jpg", 92 "http://img.my.csdn.net/uploads/201309/01/1378037095_7515.jpg", 93 "http://img.my.csdn.net/uploads/201309/01/1378037094_8001.jpg", 94 "http://img.my.csdn.net/uploads/201309/01/1378037093_7168.jpg", 95 "http://img.my.csdn.net/uploads/201309/01/1378037091_4950.jpg", 96 "http://img.my.csdn.net/uploads/201308/31/1377949643_6410.jpg", 97 "http://img.my.csdn.net/uploads/201308/31/1377949642_6939.jpg", 98 "http://img.my.csdn.net/uploads/201308/31/1377949630_4505.jpg", 99 "http://img.my.csdn.net/uploads/201308/31/1377949630_4593.jpg",100 "http://img.my.csdn.net/uploads/201308/31/1377949629_7309.jpg",101 "http://img.my.csdn.net/uploads/201308/31/1377949629_8247.jpg",102 "http://img.my.csdn.net/uploads/201308/31/1377949615_1986.jpg",103 "http://img.my.csdn.net/uploads/201308/31/1377949614_8482.jpg",104 "http://img.my.csdn.net/uploads/201308/31/1377949614_3743.jpg",105 "http://img.my.csdn.net/uploads/201308/31/1377949614_4199.jpg",106 "http://img.my.csdn.net/uploads/201308/31/1377949599_3416.jpg",107 "http://img.my.csdn.net/uploads/201308/31/1377949599_5269.jpg",108 "http://img.my.csdn.net/uploads/201308/31/1377949598_7858.jpg",109 "http://img.my.csdn.net/uploads/201308/31/1377949598_9982.jpg",110 "http://img.my.csdn.net/uploads/201308/31/1377949578_2770.jpg",111 "http://img.my.csdn.net/uploads/201308/31/1377949578_8744.jpg",112 "http://img.my.csdn.net/uploads/201308/31/1377949577_5210.jpg",113 "http://img.my.csdn.net/uploads/201308/31/1377949577_1998.jpg",114 "http://img.my.csdn.net/uploads/201308/31/1377949482_8813.jpg",115 "http://img.my.csdn.net/uploads/201308/31/1377949481_6577.jpg",116 "http://img.my.csdn.net/uploads/201308/31/1377949480_4490.jpg",117 "http://img.my.csdn.net/uploads/201308/31/1377949455_6792.jpg",118 "http://img.my.csdn.net/uploads/201308/31/1377949455_6345.jpg",119 "http://img.my.csdn.net/uploads/201308/31/1377949442_4553.jpg",120 "http://img.my.csdn.net/uploads/201308/31/1377949441_8987.jpg",121 "http://img.my.csdn.net/uploads/201308/31/1377949441_5454.jpg",122 "http://img.my.csdn.net/uploads/201308/31/1377949454_6367.jpg",123 "http://img.my.csdn.net/uploads/201308/31/1377949442_4562.jpg",124 "http://img.my.csdn.net/uploads/201309/01/1378037235_3453.jpg",125 "http://img.my.csdn.net/uploads/201309/01/1378037235_7476.jpg",126 "http://img.my.csdn.net/uploads/201309/01/1378037235_9280.jpg",127 "http://img.my.csdn.net/uploads/201309/01/1378037234_3539.jpg",128 "http://img.my.csdn.net/uploads/201309/01/1378037234_6318.jpg",129 "http://img.my.csdn.net/uploads/201309/01/1378037194_2965.jpg",130 "http://img.my.csdn.net/uploads/201309/01/1378037193_1687.jpg",131 "http://img.my.csdn.net/uploads/201309/01/1378037193_1286.jpg",132 "http://img.my.csdn.net/uploads/201309/01/1378037192_8379.jpg",133 "http://img.my.csdn.net/uploads/201309/01/1378037178_9374.jpg",134 "http://img.my.csdn.net/uploads/201309/01/1378037177_1254.jpg",135 "http://img.my.csdn.net/uploads/201309/01/1378037177_6203.jpg",136 "http://img.my.csdn.net/uploads/201309/01/1378037152_6352.jpg",137 "http://img.my.csdn.net/uploads/201309/01/1378037151_9565.jpg",138 "http://img.my.csdn.net/uploads/201309/01/1378037151_7904.jpg",139 "http://img.my.csdn.net/uploads/201309/01/1378037148_7104.jpg",140 "http://img.my.csdn.net/uploads/201309/01/1378037129_8825.jpg",141 "http://img.my.csdn.net/uploads/201309/01/1378037128_5291.jpg",142 "http://img.my.csdn.net/uploads/201309/01/1378037128_3531.jpg",143 "http://img.my.csdn.net/uploads/201309/01/1378037127_1085.jpg",144 "http://img.my.csdn.net/uploads/201309/01/1378037095_7515.jpg",145 "http://img.my.csdn.net/uploads/201309/01/1378037094_8001.jpg",146 "http://img.my.csdn.net/uploads/201309/01/1378037093_7168.jpg",147 "http://img.my.csdn.net/uploads/201309/01/1378037091_4950.jpg",148 "http://img.my.csdn.net/uploads/201308/31/1377949643_6410.jpg",149 "http://img.my.csdn.net/uploads/201308/31/1377949642_6939.jpg",150 "http://img.my.csdn.net/uploads/201308/31/1377949630_4505.jpg",151 "http://img.my.csdn.net/uploads/201308/31/1377949630_4593.jpg",152 "http://img.my.csdn.net/uploads/201308/31/1377949629_7309.jpg",153 "http://img.my.csdn.net/uploads/201308/31/1377949629_8247.jpg",154 "http://img.my.csdn.net/uploads/201308/31/1377949615_1986.jpg",155 "http://img.my.csdn.net/uploads/201308/31/1377949614_8482.jpg",156 "http://img.my.csdn.net/uploads/201308/31/1377949614_3743.jpg",157 "http://img.my.csdn.net/uploads/201308/31/1377949614_4199.jpg",158 "http://img.my.csdn.net/uploads/201308/31/1377949599_3416.jpg",159 "http://img.my.csdn.net/uploads/201308/31/1377949599_5269.jpg",160 "http://img.my.csdn.net/uploads/201308/31/1377949598_7858.jpg",161 "http://img.my.csdn.net/uploads/201308/31/1377949598_9982.jpg",162 "http://img.my.csdn.net/uploads/201308/31/1377949578_2770.jpg",163 "http://img.my.csdn.net/uploads/201308/31/1377949578_8744.jpg",164 "http://img.my.csdn.net/uploads/201308/31/1377949577_5210.jpg",165 "http://img.my.csdn.net/uploads/201308/31/1377949577_1998.jpg",166 "http://img.my.csdn.net/uploads/201308/31/1377949482_8813.jpg",167 "http://img.my.csdn.net/uploads/201308/31/1377949481_6577.jpg",168 "http://img.my.csdn.net/uploads/201308/31/1377949480_4490.jpg",169 "http://img.my.csdn.net/uploads/201308/31/1377949455_6792.jpg",170 "http://img.my.csdn.net/uploads/201308/31/1377949455_6345.jpg",171 "http://img.my.csdn.net/uploads/201308/31/1377949442_4553.jpg",172 "http://img.my.csdn.net/uploads/201308/31/1377949441_8987.jpg",173 "http://img.my.csdn.net/uploads/201308/31/1377949441_5454.jpg",174 "http://img.my.csdn.net/uploads/201308/31/1377949454_6367.jpg",175 "http://img.my.csdn.net/uploads/201309/01/1378037235_3453.jpg",176 "http://img.my.csdn.net/uploads/201309/01/1378037235_7476.jpg",177 "http://img.my.csdn.net/uploads/201309/01/1378037235_9280.jpg",178 "http://img.my.csdn.net/uploads/201309/01/1378037234_3539.jpg",179 "http://img.my.csdn.net/uploads/201309/01/1378037234_6318.jpg",180 "http://img.my.csdn.net/uploads/201309/01/1378037194_2965.jpg",181 "http://img.my.csdn.net/uploads/201309/01/1378037193_1687.jpg",182 "http://img.my.csdn.net/uploads/201309/01/1378037193_1286.jpg",183 "http://img.my.csdn.net/uploads/201309/01/1378037192_8379.jpg",184 "http://img.my.csdn.net/uploads/201309/01/1378037178_9374.jpg",185 "http://img.my.csdn.net/uploads/201309/01/1378037177_1254.jpg",186 "http://img.my.csdn.net/uploads/201309/01/1378037177_6203.jpg",187 "http://img.my.csdn.net/uploads/201309/01/1378037152_6352.jpg",188 "http://img.my.csdn.net/uploads/201309/01/1378037151_9565.jpg",189 "http://img.my.csdn.net/uploads/201309/01/1378037151_7904.jpg",190 "http://img.my.csdn.net/uploads/201309/01/1378037148_7104.jpg",191 "http://img.my.csdn.net/uploads/201309/01/1378037129_8825.jpg",192 "http://img.my.csdn.net/uploads/201309/01/1378037128_5291.jpg",193 "http://img.my.csdn.net/uploads/201309/01/1378037128_3531.jpg",194 "http://img.my.csdn.net/uploads/201309/01/1378037127_1085.jpg",195 "http://img.my.csdn.net/uploads/201309/01/1378037095_7515.jpg",196 "http://img.my.csdn.net/uploads/201309/01/1378037094_8001.jpg",197 "http://img.my.csdn.net/uploads/201309/01/1378037093_7168.jpg",198 "http://img.my.csdn.net/uploads/201309/01/1378037091_4950.jpg",199 "http://img.my.csdn.net/uploads/201308/31/1377949643_6410.jpg",200 "http://img.my.csdn.net/uploads/201308/31/1377949642_6939.jpg",201 "http://img.my.csdn.net/uploads/201308/31/1377949630_4505.jpg",202 "http://img.my.csdn.net/uploads/201308/31/1377949630_4593.jpg",203 "http://img.my.csdn.net/uploads/201308/31/1377949629_7309.jpg",204 "http://img.my.csdn.net/uploads/201308/31/1377949629_8247.jpg",205 "http://img.my.csdn.net/uploads/201308/31/1377949615_1986.jpg",206 "http://img.my.csdn.net/uploads/201308/31/1377949614_8482.jpg",207 "http://img.my.csdn.net/uploads/201308/31/1377949614_3743.jpg",208 "http://img.my.csdn.net/uploads/201308/31/1377949614_4199.jpg",209 "http://img.my.csdn.net/uploads/201308/31/1377949599_3416.jpg",210 "http://img.my.csdn.net/uploads/201308/31/1377949599_5269.jpg",211 "http://img.my.csdn.net/uploads/201308/31/1377949598_7858.jpg",212 "http://img.my.csdn.net/uploads/201308/31/1377949598_9982.jpg",213 "http://img.my.csdn.net/uploads/201308/31/1377949578_2770.jpg",214 "http://img.my.csdn.net/uploads/201308/31/1377949578_8744.jpg",215 "http://img.my.csdn.net/uploads/201308/31/1377949577_5210.jpg",216 "http://img.my.csdn.net/uploads/201308/31/1377949577_1998.jpg",217 "http://img.my.csdn.net/uploads/201308/31/1377949482_8813.jpg",218 "http://img.my.csdn.net/uploads/201308/31/1377949481_6577.jpg",219 "http://img.my.csdn.net/uploads/201308/31/1377949480_4490.jpg",220 "http://img.my.csdn.net/uploads/201308/31/1377949455_6792.jpg",221 "http://img.my.csdn.net/uploads/201308/31/1377949455_6345.jpg",222 "http://img.my.csdn.net/uploads/201308/31/1377949442_4553.jpg",223 "http://img.my.csdn.net/uploads/201308/31/1377949441_8987.jpg",224 "http://img.my.csdn.net/uploads/201308/31/1377949441_5454.jpg",225 "http://img.my.csdn.net/uploads/201308/31/1377949454_6367.jpg",226 "http://img.my.csdn.net/uploads/201309/01/1378037235_3453.jpg",227 "http://img.my.csdn.net/uploads/201309/01/1378037235_7476.jpg",228 "http://img.my.csdn.net/uploads/201309/01/1378037235_9280.jpg",229 "http://img.my.csdn.net/uploads/201309/01/1378037234_3539.jpg",230 "http://img.my.csdn.net/uploads/201309/01/1378037234_6318.jpg",231 "http://img.my.csdn.net/uploads/201309/01/1378037194_2965.jpg",232 "http://img.my.csdn.net/uploads/201309/01/1378037193_1687.jpg",233 "http://img.my.csdn.net/uploads/201309/01/1378037193_1286.jpg",234 "http://img.my.csdn.net/uploads/201309/01/1378037192_8379.jpg",235 "http://img.my.csdn.net/uploads/201309/01/1378037178_9374.jpg",236 "http://img.my.csdn.net/uploads/201309/01/1378037177_1254.jpg",237 "http://img.my.csdn.net/uploads/201309/01/1378037177_6203.jpg",238 "http://img.my.csdn.net/uploads/201309/01/1378037152_6352.jpg",239 "http://img.my.csdn.net/uploads/201309/01/1378037151_9565.jpg",240 "http://img.my.csdn.net/uploads/201309/01/1378037151_7904.jpg",241 "http://img.my.csdn.net/uploads/201309/01/1378037148_7104.jpg",242 "http://img.my.csdn.net/uploads/201309/01/1378037129_8825.jpg",243 "http://img.my.csdn.net/uploads/201309/01/1378037128_5291.jpg",244 "http://img.my.csdn.net/uploads/201309/01/1378037128_3531.jpg",245 "http://img.my.csdn.net/uploads/201309/01/1378037127_1085.jpg",246 "http://img.my.csdn.net/uploads/201309/01/1378037095_7515.jpg",247 "http://img.my.csdn.net/uploads/201309/01/1378037094_8001.jpg",248 "http://img.my.csdn.net/uploads/201309/01/1378037093_7168.jpg",249 "http://img.my.csdn.net/uploads/201309/01/1378037091_4950.jpg",250 "http://img.my.csdn.net/uploads/201308/31/1377949643_6410.jpg",251 "http://img.my.csdn.net/uploads/201308/31/1377949642_6939.jpg",252 "http://img.my.csdn.net/uploads/201308/31/1377949630_4505.jpg",253 "http://img.my.csdn.net/uploads/201308/31/1377949630_4593.jpg",254 "http://img.my.csdn.net/uploads/201308/31/1377949629_7309.jpg",255 "http://img.my.csdn.net/uploads/201308/31/1377949629_8247.jpg",256 "http://img.my.csdn.net/uploads/201308/31/1377949615_1986.jpg",257 "http://img.my.csdn.net/uploads/201308/31/1377949614_8482.jpg",258 "http://img.my.csdn.net/uploads/201308/31/1377949614_3743.jpg",259 "http://img.my.csdn.net/uploads/201308/31/1377949614_4199.jpg",260 "http://img.my.csdn.net/uploads/201308/31/1377949599_3416.jpg",261 "http://img.my.csdn.net/uploads/201308/31/1377949599_5269.jpg",262 "http://img.my.csdn.net/uploads/201308/31/1377949598_7858.jpg",263 "http://img.my.csdn.net/uploads/201308/31/1377949598_9982.jpg",264 "http://img.my.csdn.net/uploads/201308/31/1377949578_2770.jpg",265 "http://img.my.csdn.net/uploads/201308/31/1377949578_8744.jpg",266 "http://img.my.csdn.net/uploads/201308/31/1377949577_5210.jpg",267 "http://img.my.csdn.net/uploads/201308/31/1377949577_1998.jpg",268 "http://img.my.csdn.net/uploads/201308/31/1377949482_8813.jpg",269 "http://img.my.csdn.net/uploads/201308/31/1377949481_6577.jpg",270 "http://img.my.csdn.net/uploads/201308/31/1377949480_4490.jpg",271 "http://img.my.csdn.net/uploads/201308/31/1377949455_6792.jpg",272 "http://img.my.csdn.net/uploads/201308/31/1377949455_6345.jpg",273 "http://img.my.csdn.net/uploads/201308/31/1377949442_4553.jpg",274 "http://img.my.csdn.net/uploads/201308/31/1377949441_8987.jpg",275 "http://img.my.csdn.net/uploads/201308/31/1377949441_5454.jpg",276 "http://img.my.csdn.net/uploads/201308/31/1377949454_6367.jpg" };277 278 /**279 * 将大图缩放280 * 281 * @param path282 * @param mClolumnWidth283 */284 public Bitmap decodeSimpleBitMapFromResource(String path, int mClolumnWidth) {285 //第一次解析将inJustDecodeBounds设置为true,来获取图片的大小286 final Options options = new Options();287 options.inJustDecodeBounds = true;288 Bitmap bitmap = BitmapFactory.decodeFile(path, options);289 //调用方法计算insampleSize的值290 options.inSampleSize = decodeSimpleSize(options, mClolumnWidth);291 //使用获取到的inSampleSize的值292 options.inJustDecodeBounds = false;293 return BitmapFactory.decodeFile(path, options);294 295 }296 297 /**298 * 获得simpleSize299 * 300 * @param options301 * @return302 */303 private int decodeSimpleSize(Options options, int reqwidth) {304 //源图片的宽度305 int width = options.outWidth;306 int simplesize = 1;307 if (width > reqwidth) {308 //计算出实际宽度和目标宽度的比率309 simplesize = Math.round(width / reqwidth);310 }311 return simplesize;312 }313 }
第三个类
1 package com.pangzaifei.falls; 2 3 import java.io.BufferedInputStream; 4 import java.io.BufferedOutputStream; 5 import java.io.File; 6 import java.io.FileOutputStream; 7 import java.io.IOException; 8 import java.io.InputStream; 9 import java.net.HttpURLConnection; 10 import java.net.URL; 11 import java.util.ArrayList; 12 import java.util.HashSet; 13 import java.util.List; 14 import java.util.Set; 15 16 import android.content.Context; 17 import android.graphics.Bitmap; 18 import android.graphics.BitmapFactory; 19 import android.os.AsyncTask; 20 import android.os.Environment; 21 import android.os.Handler; 22 import android.os.Message; 23 import android.util.AttributeSet; 24 import android.view.MotionEvent; 25 import android.view.View; 26 import android.view.View.OnTouchListener; 27 import android.widget.ImageView; 28 import android.widget.ImageView.ScaleType; 29 import android.widget.LinearLayout; 30 import android.widget.ScrollView; 31 import android.widget.Toast; 32 33 /** 34 * 瀑布流类 <主要用到了LruCache类,缓存图片 > 35 * 36 * 原理: 1:创建3个linearlayout,设置他们的宽度,将获得的图片压缩成和3个linearlayout一样的宽度, 37 * 然后根据3个linearlayout的高度来判断,将bitmap添加到哪一个linearlayout中 38 * 2:翻页处理,根据手势抬起的位置和滑动的末尾处来进行翻页 39 * 40 */ 41 /* 42 ScrollView原理 43 视图的滚动过程,其实是在不断修改原点坐标。当手指触摸后,ScrollView会暂时拦截触摸事件, 44 使用一个计时器。假如在计时器到点后没有发生手指移动事件,那么ScrollView发送tracking events到被点击的subView; 45 若是在计时器到点后发生了移动事件,那么ScrollView取消tracking自己促发滚动。 46 */ 47 /*首先还是讲一下实现原理,瀑布流的布局方式虽然看起来好像排列的很随意,其实它是有很科学的排列规则的。 48 * 整个界面会根据屏幕的宽度划分成等宽的若干列,由于手机的屏幕不是很大,这里我们就分成三列。每当需要添加一张图片时, 49 * 会将这张图片的宽度压缩成和列一样宽,再按照同样的压缩比例对图片的高度进行压缩,然后在这三列中找出当前高度最小的一列, 50 * 将图片添加到这一列中。之后每当需要添加一张新图片时,都去重复上面的操作,就会形成瀑布流格局的照片墙 51 */ 52 public class PhotoFallScrollView extends ScrollView implements OnTouchListener { 53 /** 54 * 记录当前已加载到第几页 55 */ 56 private static int page; 57 /** 58 * 每页显示多少张图片的数量 59 */ 60 private static final int PAGE_SIZE = 8; 61 private Context mContext; 62 /** 63 * 数据源图片 64 */ 65 private Images mImagesThoumb; 66 /** 67 * task请求集合 68 */ 69 private Set<DownLoadTask> mTasks; 70 //判断是否是第一次进入 71 boolean isFirstEntr = true; 72 73 /**三列布局 74 * 75 */ 76 private LinearLayout mFirstColumn; 77 private LinearLayout mSecondColumn; 78 private LinearLayout mThirdColumn; 79 //当前第一列,第二列,第三列的高度 80 private int mFirstColumnHeight; 81 private int mSecondColumnHeight; 82 private int mThirdColumnHeight; 83 /** 84 * 每一列的宽度 85 */ 86 private int mClolumnWidth; 87 88 private long mDelay = 5; 89 /** 90 * 上次滑动的最后位置 91 */ 92 private static int lastScrollY = -1; 93 94 /** 95 * 是否已加载过一次layout,这里onLayout中的初始化只需加载一次 96 */ 97 private boolean loadOnce; 98 /** 99 * 存放图片的集合100 */101 private List<ImageView> mImageViewList = new ArrayList<ImageView>();102 103 public PhotoFallScrollView(Context context, AttributeSet attrs, int defStyle) {104 super(context, attrs, defStyle);105 this.mContext = context;106 init();107 }108 109 public PhotoFallScrollView(Context context, AttributeSet attrs) {110 super(context, attrs);111 this.mContext = context;112 init();113 }114 115 public PhotoFallScrollView(Context context) {116 super(context);117 this.mContext = context;118 init();119 }120 121 /**122 * 初始化123 */124 private void init() {125 mImagesThoumb = Images.getInstance();126 mTasks = new HashSet<DownLoadTask>();127 setOnTouchListener(this);128 }129 130 /**131 * 进行一些关键性的初始化操作,获取MyScrollView的高度以及得到第一列的宽度值。132 * 并在这里开始加载第一页的图片。 133 *134 */135 @Override136 protected void onLayout(boolean changed, int l, int t, int r, int b) {137 super.onLayout(changed, l, t, r, b);138 139 // 第一次进入就加载第一页的图片140 if (changed && !loadOnce) {141 mScrollViewHeight = this.getHeight();142 mScrollLayout = this.getChildAt(0);//从id的值为0处开始获取143 mFirstColumn = (LinearLayout) findViewById(R.id.first_column);144 mSecondColumn = (LinearLayout) findViewById(R.id.second_column);145 mThirdColumn = (LinearLayout) findViewById(R.id.third_column);146 //获取每一列的宽度147 mClolumnWidth = mFirstColumn.getWidth();148 loadOnce = true;149 //开始加载下一页的图片150 loadMoreImages();151 }152 }153 154 /**开始加载下一页的图片,每张图片都会开启一个异步线程去下载。155 * 加载图片156 */157 private void loadMoreImages() {158 if (hashSdcard()) {159 160 // 根据页数加载图片161 int startIndex = page * PAGE_SIZE;162 int endIndex = page * PAGE_SIZE + PAGE_SIZE;163 164 if (startIndex < mImagesThoumb.imageThumbs.length) {165 if (endIndex > mImagesThoumb.imageThumbs.length) {166 endIndex = mImagesThoumb.imageThumbs.length;167 }168 for (int i = startIndex; i < endIndex; i++) {169 String imageUrl = mImagesThoumb.imageThumbs[i].toString();170 if (imageUrl != null && !"".equals(imageUrl)) {171 //开始下载图片172 downLoadData(imageUrl);173 }174 }175 page++;176 } else {177 Toast.makeText(mContext, "没有更多图片了", 0).show();178 }179 } else {180 Toast.makeText(mContext, "无sdcard", 0).show();181 }182 }183 184 /**185 * 下载186 * 187 * @param imageUrl188 */189 private void downLoadData(String imageUrl) {190 DownLoadTask task = new DownLoadTask();191 mTasks.add(task);192 //执行193 task.execute(imageUrl);194 }195 196 /**197 *异步下载图片198 */199 public class DownLoadTask extends AsyncTask<String, String, Bitmap> {200 /** 201 * 图片的URL地址 202 */203 private String mImageUrl;204 205 @Override206 protected Bitmap doInBackground(String... params) {207 try {208 mImageUrl = params[0];209 Bitmap bitmapFromMemory = mImagesThoumb210 .getMemoryCache(mImageUrl);211 if (bitmapFromMemory != null) {212 return bitmapFromMemory;213 }214 if (hashSdcard()) {215 Bitmap bitmap = loadImage(mImageUrl);216 return bitmap;217 } else {218 Toast.makeText(mContext, "无sdcard,无法获取图片", 0).show();219 }220 221 } catch (Exception e) {222 e.printStackTrace();223 }224 return null;225 }226 227 @Override228 protected void onPostExecute(Bitmap bitmap) {229 super.onPostExecute(bitmap);230 // 展示图片231 if (bitmap != null) {232 // 1.缩放图片233 // 2.新建ImageView234 // 3.找到需要的linerlayout添加imageView235 float width = bitmap.getWidth();236 float radio = width / mFirstColumn.getWidth();237 float scaleHeight = bitmap.getHeight() / radio;238 addImage(bitmap, mFirstColumn.getWidth(), scaleHeight);239 }240 mTasks.remove(this);241 }242 243 /** 244 * 向ImageView中添加一张图片 245 * 246 * @param bitmap 247 * 待添加的图片 248 * @param width 249 * 图片的宽度 250 * @param scaleHeight 251 * 图片的高度 252 */ 253 public void addImage(Bitmap bitmap, float width, float scaleHeight) {254 // 生成缩放的iv255 ImageView iv = new ImageView(mContext);256 android.view.ViewGroup.LayoutParams params = new LayoutParams(257 (int) width, (int) scaleHeight);258 iv.setLayoutParams(params);259 if (bitmap != null) {260 // 解决默认图片有大有小的问题261 iv.setScaleType(ScaleType.FIT_XY);262 iv.setPadding(5, 5, 5, 5);263 264 iv.setImageBitmap(bitmap);265 iv.setTag(R.string.iamgurl, mImageUrl);266 findColumnToAdd(iv, (int) scaleHeight).addView(iv);267 mImageViewList.add(iv);268 }269 }270 271 }272 273 /**将图片下载到SD卡缓存起来。274 * @param imageUrl 图片的URL地址。 275 * @return276 * @throws IOException277 */278 private Bitmap downLoad(String imageUrl) throws IOException {279 BufferedInputStream bis = null;280 FileOutputStream fos = null;281 BufferedOutputStream bos = null;282 HttpURLConnection conn = null;283 File imageFile = null;284 try {285 URL url = new URL(imageUrl);286 conn = (HttpURLConnection) url.openConnection();287 conn.setReadTimeout(10000);288 conn.setConnectTimeout(5000);289 conn.setDoInput(true);290 conn.setDoOutput(true);291 InputStream is = conn.getInputStream();292 imageFile = new File(getImagePath(imageUrl));293 bis = new BufferedInputStream(is);294 fos = new FileOutputStream(imageFile);295 bos = new BufferedOutputStream(fos);296 int len = 0;297 byte[] buffer = new byte[1024];298 while ((len = bis.read(buffer)) != -1) {299 bos.write(buffer, 0, len);300 bos.flush();301 }302 } catch (Exception e) {303 e.printStackTrace();304 } finally {305 if (bis != null) {306 bis.close();307 }308 if (bos != null) {309 bos.close();310 }311 if (conn != null) {312 conn.disconnect();313 }314 }315 // 如果imageFile不为null,将图片添加到memory中316 if (imageFile != null) {317 Bitmap bitmap = BitmapFactory.decodeFile(imageFile.getPath());318 mImagesThoumb.addBitmapToMemoryCache(imageUrl, bitmap);319 return bitmap;320 }321 return null;322 323 }324 325 326 /** 327 * 根据传入的URL,对图片进行加载。如果这张图片已经存在于SD卡中,则直接从SD卡里读取,否则就从网络上下载。 328 * 329 * @param imageUrl 330 * 图片的URL地址 331 * @return 加载到内存的图片。 332 * 判断图片sdcard是否有图片,如果有就用,没有就下载333 */ 334 public Bitmap loadImage(String mImageUrl) throws Exception {335 File file = new File(getImagePath(mImageUrl));336 if (!file.exists()) {337 downLoad(mImageUrl);338 }339 340 if (mImageUrl != null) {341 // 处理本地图片,设置大小防止oom342 Bitmap bitmap = mImagesThoumb.decodeSimpleBitMapFromResource(343 file.getPath(), mClolumnWidth);344 // Bitmap bitmap = BitmapFactory.decodeFile(file.getPath());345 if (bitmap != null) {346 mImagesThoumb.addBitmapToMemoryCache(mImageUrl, bitmap);347 return bitmap;348 }349 }350 return null;351 }352 353 /** 354 * 找到此时应该添加图片的一列。原则就是对三列的高度进行判断,当前高度最小的一列就是应该添加的一列。 355 * 356 * @param iv 357 * @param imageHeight 358 * @return 应该添加图片的一列 359 */ 360 private LinearLayout findColumnToAdd(ImageView iv, int imageHeight) {361 if (mFirstColumnHeight <= mSecondColumnHeight) {362 if (mFirstColumnHeight <= mThirdColumnHeight) {363 iv.setTag(R.string.border_top, mFirstColumnHeight);364 mFirstColumnHeight += imageHeight;365 iv.setTag(R.string.border_bottom, mFirstColumnHeight);366 return mFirstColumn;367 }368 iv.setTag(R.string.border_top, mThirdColumnHeight);369 mThirdColumnHeight += imageHeight;370 iv.setTag(R.string.border_bottom, mThirdColumnHeight);371 return mThirdColumn;372 373 } else {374 if (mSecondColumnHeight <= mThirdColumnHeight) {375 iv.setTag(R.string.border_top, mSecondColumnHeight);376 mSecondColumnHeight += imageHeight;377 iv.setTag(R.string.border_bottom, mSecondColumnHeight);378 return mSecondColumn;379 }380 iv.setTag(R.string.border_top, mThirdColumnHeight);381 mThirdColumnHeight += imageHeight;382 iv.setTag(R.string.border_bottom, mThirdColumnHeight);383 return mThirdColumn;384 }385 }386 387 /**获取图片的本地存储路径。 388 * 获得file地址389 * 390 * @param imageUrl 图片的URL地址。391 * @return 图片的本地存储路径。392 */393 private String getImagePath(String imageUrl) {394 int lastIndexOf = imageUrl.lastIndexOf("/");395 String imageName = imageUrl.substring(lastIndexOf + 1);396 String imageDir = Environment.getExternalStorageDirectory().getPath()397 + "/pangzaifei/";398 File file = new File(imageDir);399 if (!file.exists()) {400 file.mkdir();401 }402 String imagePath = imageDir + imageName;403 return imagePath;404 }405 406 /**判断手机是否有sd卡407 * 获得图片的名字408 * 409 * @param imageUrl410 */411 412 private boolean hashSdcard() {413 if (Environment.getExternalStorageState().equals(414 Environment.MEDIA_MOUNTED)) {415 return true;416 }417 return false;418 }419 420 @Override421 /**422 * 当手势抬起时,开始每个5毫秒计算位置423 * 监听用户的触屏事件,如果用户手指离开屏幕则开始进行滚动检测。 424 */425 public boolean onTouch(View v, MotionEvent event) {426 if (event.getAction() == MotionEvent.ACTION_UP) {427 // 发送handler428 Message msg = mHandler.obtainMessage();429 msg.obj = this;430 mHandler.sendMessageDelayed(msg, mDelay);431 }432 return false;433 }434 435 /**436 * 在Handler中进行图片可见性检测的判断,以及加载更多图片的操作437 */438 private Handler mHandler = new Handler() {439 440 @Override441 public void handleMessage(Message msg) {442 super.handleMessage(msg);443 // 判断是否已经滑到了最低处,如果滑到了最低处,则加载更多页面,否则继续发送handler扫描444 PhotoFallScrollView scrollView = (PhotoFallScrollView) msg.obj;445 int scrollY = scrollView.getScrollY();446 //如果当前的滚动位置和上次相同,表示已停止滚动447 if (scrollY == lastScrollY) {448 // 当滚动的最底部,并且当前没有正在下载的任务时,开始加载下一页的图片 449 if (mScrollViewHeight + scrollY >= mScrollLayout.getHeight()450 && mTasks.isEmpty()) {451 scrollView.loadMoreImages();452 }453 scrollView.checkVisibile();454 } else {455 lastScrollY = scrollY;456 Message message = new Message();457 message.obj = scrollView;458 //5毫秒后在对滚动位置进行判断459 mHandler.sendMessageDelayed(message, mDelay);460 }461 }462 463 };464 /**465 * MyScrollView布局的高度。466 */467 private int mScrollViewHeight;468 /** 469 * MyScrollView下的直接子布局。 470 */ 471 private View mScrollLayout;472 473 /**474 * 遍历imageview中的每一张图片,对图片的可见性进行检测,如果图片已经离开屏幕可见范围,475 * 则将图片替换成一张空图476 * 想不可见的变为空图片477 */478 protected void checkVisibile() {479 if (mImageViewList != null && mImageViewList.size() > 0) {480 for (int i = 0; i < mImageViewList.size(); i++) {481 ImageView iv = mImageViewList.get(i);482 int borderTop = (Integer) iv.getTag(R.string.border_top);483 int borderBottom = (Integer) iv.getTag(R.string.border_bottom);484 if (borderBottom > getScrollY()485 && borderTop < getScrollY() + mScrollViewHeight) {486 String imageUrl = (String) iv.getTag(R.string.iamgurl);487 if (imageUrl != null && !"".equals(imageUrl)) {488 Bitmap bitmap = mImagesThoumb.getMemoryCache(imageUrl);489 if (bitmap != null) {490 iv.setImageBitmap(bitmap);491 } else {492 downLoadData(imageUrl);493 }494 }495 } else {496 //离开屏幕加载空图497 iv.setImageResource(R.drawable.empty_photo);498 }499 500 }501 }502 }503 }
LruCache类的相关知识以及代码实现
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。