【问题标题】:ListView Images showed only when visibleListView 图像仅在可见时显示
【发布时间】:2012-11-02 22:59:48
【问题描述】:

我有一个ListView,它可以将图像异步加载到ImageView。为了实现这一点,我使用Android-Universal-Image-Loader

但我想仅当它们在列表视图中可见时才开始加载这些图像。例如,如果列表视图的可见项是从 5 到 9,则只应加载那些。此外,如果用户滚动得非常快,ListView 只有在停止时才应该加载这些项目。 最好的方法是什么?

【问题讨论】:

    标签: android asynchronous android-listview universal-image-loader


    【解决方案1】:

    如果您在列表视图适配器中使用“视图重用”,那么您不应该做任何事情。 UIL 为您完成。 UIL 不会加载所有滚动的图像,只会加载任务池中的那些(您可以在配置中设置设置池大小)。如果您使用“视图重用”,则不会加载快速滚动的图像。 查看 GitHub 上的示例项目。

    UPD:从 1.7.0 版本开始,UIL 有 PauseOnScrollListener

    boolean pauseOnScroll = true;
    boolean pauseOnFling = true;
    listView.setOnScrollListener(new PauseOnScrollListener(pauseOnScroll, pauseOnFling));
    

    【讨论】:

    • 是的,我在 ViewHolder 中使用“视图重用”。因此,如果我使用“视图重用”并快速滚动这些图像不会被加载,对吧?再问一个问题,因为ImageLoader.displayImagegetView 中并且不止一次调用,ImageLoader 是否会尝试再次下载图像,尽管已经下载?
    • 对。当您使用视图重用时,当视图被重用时,先前的视图加载任务将被取消。如果您调用 displayImage() 两次并同时使用相同的 imageUri,则第二个任务将等到第一个任务加载并缓存图像。当第一个任务加载并显示图像时,第二个任务继续他的工作并显示图像。所以一张图片不会从网络加载两次。
    • PauseOnScrollListener 仅在“不在列表视图中重用视图”时使用,对吗?
    • 不,在任何情况下你都可以使用 PauseOnScrollListener。
    【解决方案2】:

    使用OnScrollListener,当ListView 在SCROLL_STATE_IDLESCROLL_STATE_TOUCH_SCROLL(滚动速度较慢)和SCROLL_STATE_FLING(滚动速度较快)之间切换时,将调用onScrollStateChanged() 方法。有了这个,您可以选择仅在状态为“空闲”或“触摸”时加载新图像。


    加法

    在第一次运行时,不会显示 ListView 的可见项。例如,当应用程序启动时,如果 ListView 有 4 个可见项目,则应加载这 4 个图像。

    我自己没有使用通用图像加载器,但是根据您在下面描述的内容,您需要知道在开始下载之前将显示多少行。。试试这个:

    • 编写一个 Runnable 以启动异步下载。
    • 使用 ListView 的内置处理程序在绘制行之后调用 Runnable

    例如:

    private Runnable loadImages = new Runnable() {
        @Override
        public void run() {
            // Start the asynchronous downloads
        }
    };
    
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        ...
        mListView.post(loadImages);
    }
    

    loadImages 将在 ListView 绘制之后被调用,这样您就可以准确地知道有多少行可见。

    【讨论】:

    • 我已经尝试过这样做。在状态为SCROLL_STATE_IDLEonScrollStateChanged 中,我找到了FirstVisiblePosition 和可见的孩子,然后循环显示图像。当我第一次运行应用程序时出现了问题。由于我从 List Adapter 的 getView 中删除了图像的加载,因此在第一次运行时未显示 ListView 的可见项。
    • 所以你需要强制图像加载之前用户滚动ListView?
    • 是的。例如,当应用程序启动时,如果 ListView 有 4 个可见项目,则应加载这 4 个图像。
    • 好的,如何启动异步下载?为什么不能在onCreate() 开始下载?
    • 我在 onScrollStateChanged 中有异步下载。要开始onCreate 的下载,我首先要查看哪些项目是可见的,然后循环列表视图行并开始正确下载?而在适配器中,我只会将行的项目文本设置正确?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-08-12
    • 2020-06-07
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多