Android 将图像加载到自定义listview-如何逐步加载?
我有一个自定义的Android 将图像加载到自定义listview-如何逐步加载?,android,android-listview,Android,Android Listview,我有一个自定义的列表视图——它包含一个图像视图、文本和一个复选框 我正在从dropbox加载图像(获取Thumnail或获取图像的共享URL),并使用ImageAdapter将它们加载到自定义Listview中 在给定文件夹中加载图像的速度非常慢。加载几张图片需要几秒钟的时间,如果有几十张图片,最多需要一分钟,我的应用程序会崩溃,如果有很多图片,我假设内存不足 从dropbox获取URL(或者如果解码流,则获取位图)似乎需要大约2秒钟的时间。因此,检索30个图像URL需要60秒。这太过分了(不知
列表视图
——它包含一个图像视图、文本和一个复选框
我正在从dropbox加载图像(获取Thumnail或获取图像的共享URL),并使用ImageAdapter
将它们加载到自定义Listview中
在给定文件夹中加载图像的速度非常慢。加载几张图片需要几秒钟的时间,如果有几十张图片,最多需要一分钟,我的应用程序会崩溃,如果有很多图片,我假设内存不足
从dropbox获取URL(或者如果解码流,则获取位图)似乎需要大约2秒钟的时间。因此,检索30个图像URL需要60秒。这太过分了(不知道为什么要花这么长时间?)
我希望我能改进我的代码,使之更快。我希望以增量方式加载图像,即保持UI响应并批量加载图像
我已经在使用一个异步任务,所以希望有人能提供建议
请注意,我已经尝试使用通用图像加载器,但加载图像仍然需要很长时间
我应该注意,我认为问题在于从dropbox检索图像数据。下面的代码检索缩略图文件,速度非常慢。我尝试更改代码来检索图像的URL链接,但执行和循环的速度非常慢
那么,在循环完成之前,循环内部是否有任何方法可以获取图像,在列表视图中开始显示数据?也就是说,不要等到OnTaskCompleted
,而是开始在doInBackground
内部显示图像
以下是异步任务的doInBackground
:
@Override
protected Boolean doInBackground(DbxFileSystem... params) {
//Opens thumbnails for each image contained in the dropbox folder
try {
DbxFileSystem fileSystem = params[0];
for (DbxFileInfo fileInfo: fileSystem.listFolder(currentPath)) {
DbxFile file;
//this code below is very slow to execute
try{
if(fileInfo.thumbExists) // if it has a thumbnail then retrieve it
{
file = fileSystem.openThumbnail(fileInfo.path, ThumbSize.XS, ThumbFormat.PNG);
Bitmap image = BitmapFactory.decodeStream(file.getReadStream());
pix.add(image); // image to display in the custom listview
paths.add(fileInfo.path); // path to display in the custom listview
file.close();
}
else
{
//must be a folder if it has no thumb, so add local drawable folder icon
Bitmap image = BitmapFactory.decodeResource(getResources(), R.drawable.dbfolder);
pix.add(image);
paths.add(fileInfo.path);
}
}catch (DbxException e1) {
e1.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
System.gc();
}
}
catch (Exception e) {
e.printStackTrace();
return false;
} finally {
loadingDialog.dismiss();
}
return true;
}
然后在onTaskCompleted中设置图像适配器:
public void onTaskCompleted(int requestID, ArrayList<Bitmap> urls, ArrayList<DbxPath> path) {
lstView = (ListView) findViewById(R.id.lstView);
this.paths = path;
ImageAdapter adapter = new ImageAdapter(this, urls, paths);
lstView.setAdapter(adapter);
}
为此,您可以使用Universal-Image-loader-jar
Universal-Image-loader-1.9.2-SNAPSHOT-with-sources.jar
那么适配器是这样的
public class LinkAdapter extends ArrayAdapter<MediaModel>{
ArrayList<MediaModel> medias;
Activity context;
ImageLoader imageLoader;
DisplayImageOptions options;
public LinkAdapter(Activity context, int textViewResourceId,
ArrayList<MediaModel> objects) {
super(context, textViewResourceId, objects);
this.medias = objects;
this.context = context;
imageLoader = ImageLoader.getInstance();
imageLoader.init(ImageLoaderConfiguration.createDefault(context));
options = new DisplayImageOptions.Builder()
.showImageOnLoading(R.drawable.ic_launcher)
.showImageForEmptyUri(R.drawable.ic_launcher)
.showImageOnFail(R.drawable.ic_launcher).cacheInMemory(true)
.cacheOnDisc(true).considerExifParams(true)
.bitmapConfig(Bitmap.Config.RGB_565).build();
}
static class ViewHolder {
TextView title;
TextView description;
ImageView iconImage;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
View v = convertView;
ViewHolder holder;
if (convertView == null) {
LayoutInflater vi = (LayoutInflater) getContext()
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
v = vi.inflate(R.layout.link_row, null);
holder = new ViewHolder();
holder.title = (TextView) v.findViewById(R.id.txt_row_title);
holder.description = (TextView) v.findViewById(R.id.txt_row_description);
holder.iconImage = (ImageView) v.findViewById(R.id.img_row_icon);
v.setTag(holder);
} else {
holder = (ViewHolder) v.getTag();
}
holder.title.setText(medias.get(position).mediaTitle);
holder.description.setText(medias.get(position).mediaInfo);
imageLoader.displayImage(medias.get(position).mediaThumbImgUrl, holder.iconImage,options);
return v;
}
}
公共类链接适配器扩展了ArrayAdapter{
ArrayList媒体;
活动语境;
图像加载器;
显示图像选项;
公共链接适配器(活动上下文,int textViewResourceId,
ArrayList对象){
超级(上下文、textViewResourceId、对象);
this.medias=对象;
this.context=上下文;
imageLoader=imageLoader.getInstance();
init(ImageLoaderConfiguration.createDefault(上下文));
选项=新建DisplayImageOptions.Builder()
.showImageOnLoading(R.drawable.ic_启动器)
.showImageForEmptyUri(R.drawable.ic_发射器)
.showImageOnFail(R.drawable.ic_启动器).cacheInMemory(true)
.cacheOnDisc(真)。considerExifParams(真)
.bitmapConfig(Bitmap.Config.RGB_565).build();
}
静态类视窗夹{
文本视图标题;
文本视图描述;
图像视图图像;
}
@凌驾
公共视图getView(int位置、视图转换视图、视图组父视图){
视图v=转换视图;
视窗座;
if(convertView==null){
LayoutInflater vi=(LayoutInflater)getContext()
.getSystemService(上下文布局\充气机\服务);
v=vi.充气(R.布局.链接行,空);
holder=新的ViewHolder();
holder.title=(TextView)v.findViewById(R.id.txt\u row\u title);
holder.description=(TextView)v.findViewById(R.id.txt\u row\u description);
holder.iconImage=(ImageView)v.findViewById(R.id.img\u row\u图标);
v、 setTag(支架);
}否则{
holder=(ViewHolder)v.getTag();
}
holder.title.setText(medias.get(position.mediaTitle));
holder.description.setText(medias.get(position.mediaInfo));
imageLoader.displayImage(medias.get(position.mediatumbimgur,holder.iconImage,options);
返回v;
}
}
试试这个库是的,我已经试过了,并传入了URL。但问题是,我的自定义ListView在几秒钟或更长时间后才会开始填充。很明显,它会在图像下载后显示图像。我知道如何逐渐显示图像,例如,在2下载后显示图像,然后在后台继续下载其他图像。我不想等到它们全部下载完毕后才显示出来。我上面提到的库正是你刚才所说的。你试过了吗。它显示了第一个在后台下载并继续下载图像的图像。我已经尝试过这种方法,但我想加快获取图像(或URL使用图像加载器)的循环。看到主线了吗
public class LinkAdapter extends ArrayAdapter<MediaModel>{
ArrayList<MediaModel> medias;
Activity context;
ImageLoader imageLoader;
DisplayImageOptions options;
public LinkAdapter(Activity context, int textViewResourceId,
ArrayList<MediaModel> objects) {
super(context, textViewResourceId, objects);
this.medias = objects;
this.context = context;
imageLoader = ImageLoader.getInstance();
imageLoader.init(ImageLoaderConfiguration.createDefault(context));
options = new DisplayImageOptions.Builder()
.showImageOnLoading(R.drawable.ic_launcher)
.showImageForEmptyUri(R.drawable.ic_launcher)
.showImageOnFail(R.drawable.ic_launcher).cacheInMemory(true)
.cacheOnDisc(true).considerExifParams(true)
.bitmapConfig(Bitmap.Config.RGB_565).build();
}
static class ViewHolder {
TextView title;
TextView description;
ImageView iconImage;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
View v = convertView;
ViewHolder holder;
if (convertView == null) {
LayoutInflater vi = (LayoutInflater) getContext()
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
v = vi.inflate(R.layout.link_row, null);
holder = new ViewHolder();
holder.title = (TextView) v.findViewById(R.id.txt_row_title);
holder.description = (TextView) v.findViewById(R.id.txt_row_description);
holder.iconImage = (ImageView) v.findViewById(R.id.img_row_icon);
v.setTag(holder);
} else {
holder = (ViewHolder) v.getTag();
}
holder.title.setText(medias.get(position).mediaTitle);
holder.description.setText(medias.get(position).mediaInfo);
imageLoader.displayImage(medias.get(position).mediaThumbImgUrl, holder.iconImage,options);
return v;
}
}