Android瀑布流照片

http://blog.csdn.net/guolin_blog/article/details/10470797

记得我在之前已经写过一篇关于如何在Android上实现照片墙功能的文章了,但那个时候是使用的GridView来进行布局的,这种布局方式只适用于“墙”上的每张图片大小都相同的情况,如果图片的大小参差不齐,在GridView中显示就会非常的难看。而使用瀑布流的布局方式就可以很好地解决这个问题,因此今天我们也来赶一下潮流,看看如何在Android上实现瀑布流照片墙的功能。

首先还是讲一下实现原理,瀑布流的布局方式虽然看起来好像排列的很随意,其实它是有很科学的排列规则的。整个界面会根据屏幕的宽度划分成等宽的若干列,由于手机的屏幕不是很大,这里我们就分成三列。每当需要添加一张图片时,会将这张图片的宽度压缩成和列一样宽,再按照同样的压缩比例对图片的高度进行压缩,然后在这三列中找出当前高度最小的一列,将图片添加到这一列中。之后每当需要添加一张新图片时,都去重复上面的操作,就会形成瀑布流格局的照片墙,示意图如下所示。

实现主要思路:

封装一个ImageLoader类,用于图片管理,缓存和压缩

public class ImageLoader {  
  
    /** 
     * 图片缓存技术的核心类,用于缓存所有下载好的图片,在程序内存达到设定值时会将最少最近使用的图片移除掉。 
     */  
    private static LruCache<String, Bitmap> mMemoryCache;  
  
    /** 
     * ImageLoader的实例。 
     */  
    private static ImageLoader mImageLoader;  
  
    private ImageLoader() {  
        // 获取应用程序最大可用内存  
        int maxMemory = (int) Runtime.getRuntime().maxMemory();  
        int cacheSize = maxMemory / 8;  
        // 设置图片缓存大小为程序最大可用内存的1/8  
        mMemoryCache = new LruCache<String, Bitmap>(cacheSize) {  
            @Override  
            protected int sizeOf(String key, Bitmap bitmap) {  
                return bitmap.getByteCount();  
            }  
        };  
    }  
  
    /** 
     * 获取ImageLoader的实例。 
     *  
     * @return ImageLoader的实例。 
     */  
    public static ImageLoader getInstance() {  
        if (mImageLoader == null) {  
            mImageLoader = new ImageLoader();  
        }  
        return mImageLoader;  
    }  
  
    /** 
     * 将一张图片存储到LruCache中。 
     *  
     * @param key 
     *            LruCache的键,这里传入图片的URL地址。 
     * @param bitmap 
     *            LruCache的键,这里传入从网络上下载的Bitmap对象。 
     */  
    public void addBitmapToMemoryCache(String key, Bitmap bitmap) {  
        if (getBitmapFromMemoryCache(key) == null) {  
            mMemoryCache.put(key, bitmap);  
        }  
    }  
  
    /** 
     * 从LruCache中获取一张图片,如果不存在就返回null。 
     *  
     * @param key 
     *            LruCache的键,这里传入图片的URL地址。 
     * @return 对应传入键的Bitmap对象,或者null。 
     */  
    public Bitmap getBitmapFromMemoryCache(String key) {  
        return mMemoryCache.get(key);  
    }  
  
    public static int calculateInSampleSize(BitmapFactory.Options options,  
            int reqWidth) {  
        // 源图片的宽度  
        final int width = options.outWidth;  
        int inSampleSize = 1;  
        if (width > reqWidth) {  
            // 计算出实际宽度和目标宽度的比率  
            final int widthRatio = Math.round((float) width / (float) reqWidth);  
            inSampleSize = widthRatio;  
        }  
        return inSampleSize;  
    }  
  
    public static Bitmap decodeSampledBitmapFromResource(String pathName,  
            int reqWidth) {  
        // 第一次解析将inJustDecodeBounds设置为true,来获取图片大小  
        final BitmapFactory.Options options = new BitmapFactory.Options();  
        options.inJustDecodeBounds = true;  
        BitmapFactory.decodeFile(pathName, options);  
        // 调用上面定义的方法计算inSampleSize值  
        options.inSampleSize = calculateInSampleSize(options, reqWidth);  
        // 使用获取到的inSampleSize值再次解析图片  
        options.inJustDecodeBounds = false;  
        return BitmapFactory.decodeFile(pathName, options);  
    }  
  
}
原文地址:https://www.cnblogs.com/qlky/p/5700000.html