本文最后更新于 91 天前,其中的信息可能已经有所发展或是发生改变。
getView内通过parent来获取ListView/GridView findViewWithTag方法去获取对应的ImageView(ImageView设置tag)
public class GmGalleryGridAdapter extends BaseAdapter {
private Context context;
private List<GmLocalMedia> data;
private final ExecutorService executorService;
private static final int CPU_COUNT = Runtime.getRuntime().availableProcessors(); // CPU 核心数
private static final int THREAD_POOL_SIZE = Math.min(CPU_COUNT * 2, 4); // 线程池大小
private final ArrayList<Future<?>> activeTasks = new ArrayList<>();
private LruCache<String, Bitmap> mBitmapCache; // 使用 LruCache 来缓存图片
private OnSelectGalleryListener selectGalleryListener;
public GmGalleryGridAdapter(Context context, List<GmLocalMedia> data,OnSelectGalleryListener onSelectGalleryListener) {
this.context = context;
this.data = data;
this.selectGalleryListener = onSelectGalleryListener;
// 初始化线程池
executorService = Executors.newFixedThreadPool(THREAD_POOL_SIZE);
// 初始化 LruCache
final int maxMemory = (int) (Runtime.getRuntime().maxMemory() / 1024); // 获取最大内存
final int cacheSize = maxMemory / 8; // 设置缓存大小为最大内存的 1/8
mBitmapCache = new LruCache<String, Bitmap>(cacheSize) {
@Override
protected int sizeOf(String key, Bitmap value) {
return value.getByteCount() / 1024; // 返回图片的内存占用
}
};
}
@Override
public int getCount() {
return data.size();
}
@Override
public Object getItem(int position) {
return data.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
private GridView mGridView;
@Override
public View getView(int position, View convertView, ViewGroup parent) {
if (mGridView == null) {
mGridView = (GridView) parent;
}
GmLocalMedia media = data.get(position);
String path = media.getPath();
String fileName = media.getFileName();
View view;
ViewHolder viewHolder;
if (convertView == null) {
view = Ext.getLayoutView("gamehelper_gallery_item");
viewHolder = new ViewHolder();
viewHolder.img = (ImageView) Ext.getWidgetView(view,"gamehelper_gallery_item_img");
view.setTag(viewHolder);
} else {
view = convertView;
viewHolder = (ViewHolder) view.getTag();
}
Uri uri = GmMediaUtils.isContent(path) ? Uri.parse(path) : Uri.fromFile(new File(path));
view.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Log.d("dqs",">>>>>>>>>>>>>> 选择的图片文件大小 " + media.getSize());
if(media.getSize() > 20 * 1024 * 1024) {
Ext.toast("请选择小于20M的图片", Toast.LENGTH_SHORT);
return;
}
if(selectGalleryListener != null) {
selectGalleryListener.onSelectGallery(uri,fileName);
}
}
});
viewHolder.img.setTag(uri);
viewHolder.img.setImageBitmap(BitmapFactory.decodeResource(context.getResources(), Ext.getDrawableId("gamehelper_image_placeholder")));
// 检查缓存,若存在则直接加载缓存图片
Bitmap bitmap = mBitmapCache.get(uri.toString());
if (bitmap != null) {
viewHolder.img.setImageBitmap(bitmap);
} else {
loadImageAsync(uri, viewHolder, position); // 图片缓存中没有,异步加载
}
return view;
}
private Handler mHandler = new Handler(Looper.getMainLooper());
// 用来跟踪每个图片加载任务
private void loadImageAsync(Uri uri, ViewHolder viewHolder, int position) {
Runnable runnable = new Runnable() {
@Override
public void run() {
Bitmap bitmap = loadImage(uri); // 从磁盘或网络加载图片
mBitmapCache.put(uri.toString(), bitmap); // 缓存图片
if (bitmap != null) {
// 在主线程更新 UI
mHandler.post(new Runnable() {
@Override
public void run() {
ImageView view = mGridView.findViewWithTag(uri);
if (view != null) {
view.setImageBitmap(bitmap);
}
}
});
}
}
};
executorService.submit(runnable);
}
private Bitmap loadImage(Uri uri) {
try {
// 判断 URI 是否是 file:// 开头
if (uri != null) {
try {
InputStream inputStream = context.getContentResolver().openInputStream(uri);
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeStream(inputStream, null, options);
// 计算适当的采样率
options.inSampleSize = calculateInSampleSize(options, 80, 80); // 根据需求调整目标宽高
options.inJustDecodeBounds = false;
// 重新打开输入流并加载图片
InputStream inputStreamForBitmap = context.getContentResolver().openInputStream(uri);
return BitmapFactory.decodeStream(inputStreamForBitmap, null, options);
} catch (Exception e) {
Log.d("dqs", ">>>>>> " + uri + "<>" + e.getMessage());
}
}
} catch (Exception e) {
Log.d("dqs", "Error decoding image", e);
}
return null;
}
private int calculateInSampleSize(BitmapFactory.Options options, int reqWidth, int reqHeight) {
int height = options.outHeight;
int width = options.outWidth;
int inSampleSize = 1;
if (height > reqHeight || width > reqWidth) {
final int halfHeight = height / 2;
final int halfWidth = width / 2;
while ((halfHeight / inSampleSize) >= reqHeight && (halfWidth / inSampleSize) >= reqWidth) {
inSampleSize *= 2;
}
}
return inSampleSize;
}
static class ViewHolder {
ImageView img;
}
}