RecyclerView:如何仅在用户停止滚动时加载项目?

时间:2015-09-12 17:05:31

标签: android performance android-recyclerview recycler-adapter

目前,我正在开发一个启动器应用程序。该应用程序必须将所有图标加载到内存中。在某些旧设备中,当我通过PackageManager加载应用图标时,应用会崩溃。这就是为什么我目前在后台主题中onBindViewHolder(...) RecyclerView方法中加载图标的原因:

@Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
    // ...

    Thread t = new Thread(new Runnable() {
        @Override
        public void run() {
            try {
                handler.postAtFrontOfQueue(new Runnable() {
                    Drawable drawable = activity.getPackageManager().getApplicationIcon(app.name.toString());

                    @Override
                    public void run() {
                        viewHolder.appIconIv.setImageDrawable(drawable);
                    }
                });
            } catch (PackageManager.NameNotFoundException e) {
                e.printStackTrace();
            }
        }
    });
    t.start();

    // ...
}

但是,这里的问题是,即使在后台加载图标,RecyclerView在滚动时也会停滞不前/滞后。另外,如果我滚动到底部,所有图标都会加载到内存中,导致应用程序在较旧的设备上崩溃(RAM较少)。此外,我不认为这是一个很好的解决方案,因为它必须为视图的每个绑定创建一个新线程。所以,我的问题是,是否可以知道用户是否已经停止滚动(然后只加载图标)。

  

除了主要问题之外,我提到的任何问题的任何帮助都是真的非常赞赏,我将非常感激。 [特别是所有那些性能/ RAM问题:(]

提前致谢。 :d

2 个答案:

答案 0 :(得分:1)

首先,我会建议不要使用postAtFrontOfQueue,因为害怕推回其他东西。如果你把事情推到前面,就会有可能永远不会被执行的事件导致奇怪的行为。

在我正在开发的应用程序中,我正在等待用毕加索加载图像,直到用户使用当前实现完成滚动/投掷。

recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
        @Override
        public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
            super.onScrollStateChanged(recyclerView, newState);
            if (newState == RecyclerView.SCROLL_STATE_IDLE) {
                mPicasso.resumeTag(FeedViewHolder.SEARCH_IMAGE_TAG);
            }
        }

        @Override
        public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
            super.onScrolled(recyclerView, dx, dy);
            if (Math.abs(dy) > SCROLL_THRESHOLD) {
                mPicasso.pauseTag(FeedViewHolder.SEARCH_IMAGE_TAG);
            } else {
                mPicasso.resumeTag(FeedViewHolder.SEARCH_IMAGE_TAG);
            }
        }
    });

您可以使用picasso加载可绘制资源并像这样设置标记

mPicasso.load(R.drawable.image_resource_name)
                .fit()
                .centerCrop()
                .tag(SEARCH_IMAGE_TAG)
                .into(imageView);

答案 1 :(得分:1)

来自博客:Image Loading with Picasso

  1. 自定义RecyclerView.OnScrollListener
  2. Singleton Picasso
  3. Picasso.pauseTag()

    RecyclerView.addOnScrollListener(new PicassoOnScrollListener(this));

    Picasso.with(imageView.getContext()。getApplicationContext())         .load(URL)         .TAG(PicassoOnScrollListener.TAG)         .into(ImageView的);