最近项目中用到gridView显示图片,一开始自然而然的就想到显示图片用Android-Universal-Image-Loader,结果在gridview中却发现不能显示本地图片,试了多次还是不知道什么原因;如果布局文件中单独的一个imageview调用imageLoader却可以正常显示。说明我的imageLoader配置没错,很有可能这个框架和gridview结合并且加载本地图片有问题。所以我就打算自己写一个工具专门用来加载本地图片。动手之前突然想到google的volley也有一个加载图片的工具类,只不过volley只适合加载网络图片。所以就想到借用volley的图片解析方法自己写一个图片加载工具,哈哈,是不是很好。
代码呈上:
package com.hai.utils;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.widget.ImageView;
/**
* Created by 黄海 on 2016/1/20.
*/
public class ImageLoader {
/**
* 解析本地图片
*
* @param url 本地图片文件目录
* @param mMaxWidth
* @param mMaxHeight
* @param mScaleType
* @param mDecodeConfig
* @return
*/
public static Bitmap parseFile(String url, int mMaxWidth, int mMaxHeight, ImageView.ScaleType mScaleType, Bitmap.Config mDecodeConfig) {
// byte[] data = response.data;
BitmapFactory.Options decodeOptions = new BitmapFactory.Options();
Bitmap bitmap = null;
if (mMaxWidth == 0 && mMaxHeight == 0) {
decodeOptions.inPreferredConfig = mDecodeConfig;
//原来是解析网络请求返回的字节数组
// bitmap = BitmapFactory.decodeByteArray(data, 0, data.length, decodeOptions);
bitmap = BitmapFactory.decodeFile(url, decodeOptions);
} else {
// If we have to resize this image, first get the natural bounds.
decodeOptions.inJustDecodeBounds = true;
BitmapFactory.decodeFile(url, decodeOptions);
int actualWidth = decodeOptions.outWidth;
int actualHeight = decodeOptions.outHeight;
// Then compute the dimensions we would ideally like to decode to.
int desiredWidth = getResizedDimension(mMaxWidth, mMaxHeight,
actualWidth, actualHeight, mScaleType);
int desiredHeight = getResizedDimension(mMaxHeight, mMaxWidth,
actualHeight, actualWidth, mScaleType);
// Decode to the nearest power of two scaling factor.
decodeOptions.inJustDecodeBounds = false;
// TODO(ficus): Do we need this or is it okay since API 8 doesn't support it?
// decodeOptions.inPreferQualityOverSpeed = PREFER_QUALITY_OVER_SPEED;
decodeOptions.inSampleSize =
findBestSampleSize(actualWidth, actualHeight, desiredWidth, desiredHeight);
// Bitmap tempBitmap =
// BitmapFactory.decodeByteArray(data, 0, data.length, decodeOptions);
Bitmap tempBitmap =
BitmapFactory.decodeFile(url, decodeOptions);
// If necessary, scale down to the maximal acceptable size.
if (tempBitmap != null && (tempBitmap.getWidth() > desiredWidth ||
tempBitmap.getHeight() > desiredHeight)) {
bitmap = Bitmap.createScaledBitmap(tempBitmap,
desiredWidth, desiredHeight, true);
tempBitmap.recycle();
} else {
bitmap = tempBitmap;
}
}
return bitmap;
}
/**
* 获取期望的width和heigth
*
* @param maxPrimary
* @param maxSecondary
* @param actualPrimary
* @param actualSecondary
* @param scaleType
* @return
*/
private static int getResizedDimension(int maxPrimary, int maxSecondary, int actualPrimary,
int actualSecondary, ImageView.ScaleType scaleType) {
// If no dominant value at all, just return the actual.
if ((maxPrimary == 0) && (maxSecondary == 0)) {
return actualPrimary;
}
// If ScaleType.FIT_XY fill the whole rectangle, ignore ratio.
if (scaleType == ImageView.ScaleType.FIT_XY) {
if (maxPrimary == 0) {
return actualPrimary;
}
return maxPrimary;
}
// If primary is unspecified, scale primary to match secondary's scaling ratio.
if (maxPrimary == 0) {
double ratio = (double) maxSecondary / (double) actualSecondary;
return (int) (actualPrimary * ratio);
}
if (maxSecondary == 0) {
return maxPrimary;
}
double ratio = (double) actualSecondary / (double) actualPrimary;
int resized = maxPrimary;
// If ScaleType.CENTER_CROP fill the whole rectangle, preserve aspect ratio.
if (scaleType == ImageView.ScaleType.CENTER_CROP) {
if ((resized * ratio) < maxSecondary) {
resized = (int) (maxSecondary / ratio);
}
return resized;
}
if ((resized * ratio) > maxSecondary) {
resized = (int) (maxSecondary / ratio);
}
return resized;
}
/**
* 计算缩放比例
*
* @param actualWidth
* @param actualHeight
* @param desiredWidth
* @param desiredHeight
* @return
*/
static int findBestSampleSize(
int actualWidth, int actualHeight, int desiredWidth, int desiredHeight) {
double wr = (double) actualWidth / desiredWidth;
double hr = (double) actualHeight / desiredHeight;
double ratio = Math.min(wr, hr);
float n = 1.0f;
while ((n * 2) <= ratio) {
n *= 2;
}
return (int) n;
}
}
我写的这个imageloader的图片解析代码基本是借用volley的ImageRequest中的代码,两者的区别在于一个是用于加载本地图片,一个加载网络图片。
文中我提到两点:
- Universal-Image-Loader,和gridview结合不好用,常不能显示本地图片
- volley的图片加载也不适用与本地图片
不知大家是否认同我的这两点,如果不认同,还请指正