我需要将Bitmaps加载到ArrayList中,然后将其转换为Bitmap []并传递给ArrayAdapter以扩充ListView。我使用UniversalImageLoader库,这是我的代码:
final ArrayList<Bitmap> imgArray = new ArrayList<>(); //before the method scope, as a class field
//...some code...
File cacheDir = StorageUtils.getOwnCacheDirectory(
getApplicationContext(),
"/sdcard/Android/data/random_folder_for_cache");
DisplayImageOptions options = new DisplayImageOptions.Builder()
.cacheInMemory(true).cacheOnDisc(true).build();
ImageLoaderConfiguration config = new ImageLoaderConfiguration.Builder(
getApplicationContext()).defaultDisplayImageOptions(options)
//.discCache(new FileCounterLimitedCache(cacheDir, 100)) - I commented it 'cause FileCounterLimitedCache isn't recognized for some reason
.build();
ImageLoader.getInstance().init(config);
for (int num=0;num<4;num++) {
ImageLoader imageLoader = ImageLoader.getInstance();
final int constNum = num;
imageLoader.loadImage("http://example.com/sample.jpg", new SimpleImageLoadingListener()
{
@Override
public void onLoadingComplete(String imageUri, View view, Bitmap loadedImage)
{
imgArray.add(constNum, loadedImage);
}
});
}
但我有一些问题需要努力。首先,它在第一次运行时经常返回错误(IndexOutOfBoundsException - 当前索引超过ArrsyList的大小)。然后在一段时间(大约一分钟)之后,ArrayList的大小为1(我用Toast检查),然后当立即再次运行时,它已经是4(因为它需要)。奇怪。但是我需要首先填充ArrayList,然后完成所有其他操作(它们会被延迟并且我在第一次运行时没有错误)。怎么做?
如果有人没有SD卡怎么办?顺便说一下,我无法在SD上找到创建的缓存文件夹......
答案 0 :(得分:0)
您无法按照您尝试的方式添加元素。例如,如果第二张图片首先完成加载,则代码会正确抛出IndexOutOfBoundsException
,因为您尝试添加的位置超出当前大小 - 请参阅the documentation
你可能最好使用一个数组初始化为元素数量,因为你知道它的4个元素 - 例如
final Bitmap[] imgArray = new Bitmap[4];
然后使用
添加onLoadingComplete()
中的元素
imgArray[constNum] = loadedImage;
答案 1 :(得分:0)
您可以使用SparseArray
代替ArrayList
来避免使用IndexOutOfBoundsException
。
我认为这就是你所追求的:
final SparseArray<Bitmap> imgArray = new SparseArray<>(); //before the method scope, as a class field
int numberOfImages;
int numberOfLoadedImages;
//...some code...
File cacheDir = StorageUtils.getOwnCacheDirectory(
getApplicationContext(),
"/sdcard/Android/data/random_folder_for_cache");
DisplayImageOptions options = new DisplayImageOptions.Builder()
.cacheInMemory(true).cacheOnDisc(true).build();
ImageLoaderConfiguration config = new ImageLoaderConfiguration.Builder(
getApplicationContext()).defaultDisplayImageOptions(options)
//.discCache(new FileCounterLimitedCache(cacheDir, 100)) - I commented it 'cause FileCounterLimitedCache isn't recognized for some reason
.build();
ImageLoader.getInstance().init(config);
numberOfImages = 4;
numberOfLoadedImages = 0;
for (int num=0;num<4;num++) {
ImageLoader imageLoader = ImageLoader.getInstance();
final int constNum = num;
imageLoader.loadImage("http://example.com/sample.jpg", new SimpleImageLoadingListener()
{
@Override
public void onLoadingComplete(String imageUri, View view, Bitmap loadedImage)
{
imgArray.put(constNum, loadedImage);
numberOfLoadedImages++;
if(numberOfImages == numberOfLoadedImages)
{
//Do all the other actions
}
}
});
}
答案 2 :(得分:0)
Universal Image Loader库包含以下方法:
public void displayImage(java.lang.String uri, android.widget.ImageView imageView)
可以传递图片网址和ImageView
以在其上显示图片。
加上那个,如果以后相同的ImageView
传递给方法,但使用不同的网址,可能会发生两件事:
如果已经下载旧图像,通常新图像将被设置为ImageView。
- 醇>
如果仍在下载库的旧图像将取消正在下载旧图像的http连接。并开始下载 新形象。 (可以在LogCat中观察到)。这种行为发生了 使用适配器时。
方法调用:
ImageLoader.getInstance().displayImage("http://hydra-media.cursecdn.com/dota2.gamepedia.com/b/bd/Earthshaker.png", imageView1);
<强>配置:强>
如果未指定defaultDisplayImageOptions,则缓存将不起作用。告诉图书馆在哪里保存这些图像。因为这个库有从Assets,Drawables或Internet加载图像的选项:
DisplayImageOptions opts = new DisplayImageOptions.Builder().cacheInMemory(true).cacheOnDisk(true).build();
使用此选项,图像将保存在应用程序中。内部存储器。 不要担心设备是否有外部存储器。
ImageLoaderConfiguration config = new ImageLoaderConfiguration.Builder(this)
.defaultDisplayImageOptions(opts)
.memoryCache(new LruMemoryCache(2 * 1024 * 1024))
.memoryCacheSize(2 * 1024 * 1024)
.diskCacheSize(50 * 1024 * 1024)
.diskCacheFileCount(100)
.writeDebugLogs()
.build();
ImageLoader.getInstance().init(config);