Android:关闭listview的延迟加载

时间:2010-11-01 22:07:21

标签: android listview

在我的Android应用程序中,我有一个包含30行的列表视图,每行包含几个文本视图,其中一个是可跨越的,有时包含大量格式化的文本和图像。

这些图像是从网络上异步加载的:显示占位符,直到图像被下载后再被图像替换。

不幸的是,当我滚动它们时会加载listview的行。这使整个事情变得非常缓慢。此外,每当我滚动行时,这些图像会一次又一次地从Web加载。

如何关闭它,当我滚动它们时会加载ListView行?当我开始活动时,它们应该被加载一次,而不是再次加载。

提前致以最诚挚的问候和谢意, Jan Oliver

3 个答案:

答案 0 :(得分:5)

当您执行延迟加载ListView时,是因为您希望加快应用程序的速度。关闭它不是最好的解决方案。因此,您可以做的是实现一个基本的缓存系统,以避免一次又一次地下载和设置ImageView。

最简单的方法是实现一个HashMap,其中URL作为键,位图作为值。像这样:

Map cache = new HashMap();
// then, on your lazy loader
Bitmap image = cache.get(urlOfTheImage);
if( image == null ){
    // download and decode the image as normal,
    // then assign the decoded bitmap to
    // the 'image' variable
    cache.put(image);
}
imageView.setImageBitmap(image);

如果这些图像总是相同的,这意味着每次打开应用程序时都会下载相同的图像,然后您最好将这些图像保存在文件系统中并从那里使用它们。

另一方面,如果图像倾向于改变,你可以实现一些有趣的东西:使用SoftReferences。在this video中有一个解释。如果从文件系统加载图像,也可以使用它。

修改

关于您的评论,我强烈建议您观看我发布的视频。这是一个小时,但它确实值得努力。使用适配器时,检查convertView是否为null只是提高性能的一种简单方法,尽管还有一些其他技术可以进一步改善您的应用程序。此外,如果您在使用该技巧时遇到问题,那是因为您可能以错误的方式实现它。请记住:即使您没有重新夸大视图,也必须设置每个子视图的值,否则您将遇到一些问题。

答案 1 :(得分:1)

如果可以,请从充满“占位符图像”的图像阵列开始,然后在创建期间将图像下载到阵列中触发AsyncTask。在行视图构建期间,只需引用该数组。这样,如果它有新图像,它将加载它,如果不是它将获得占位符。

如果您拥有大量数据,那么它将变得非常缓慢并且对用户来说是一个糟糕的经验。

答案 2 :(得分:0)

创建表示每行的对象列表。创建一个加载器作为后台线程,在加载数据时更新对象。列表视图将从对象中提取数据。

(如果你在每行中有数百行和大量数据,那不是一个好主意 - 在这种情况下,你应该只在当前活动行的几行内加载数据并拥有某种MRU缓存)