【问题标题】:RecyclerView lazy loading TextView contentRecyclerView 懒加载 TextView 内容
【发布时间】:2017-01-19 10:40:19
【问题描述】:

我正在用来自sqlite database 的多达数千个条目填充RecyclerView,通过AsyncTaskLoader 加载。该列表需要可过滤,因此我需要一次加载所有条目。 RecyclerView 的 ViewHolders 中的一些 TextViews 包含进一步的数据库查询(基于初始结果)或其他类型的计算的结果。

扩展初始查询以包含 JOIN(这至少会使辅助查询过时)确实会减慢加载速度。然而,在 RecyclerView 的 onBind 方法中进行查询/计算,使得投掷比没有它们时流畅得多。

有没有办法延迟加载这些计算出的TextViews 的内容?我已经搜索了示例,但是像“Picasso”和“Glide”这样的库只允许加载图像......

任何帮助表示赞赏!

谢谢, 抢

【问题讨论】:

  • 使用this适配器
  • @pskink:谢谢,但这个适配器并不真正适合我的需要......
  • 只需使用 JOINS,不,对于过滤,您不需要一次加载所有条目,只需覆盖 runQueryOnBackgroundThread 或设置其 FilterQueryProvider

标签: android android-recyclerview lazy-loading


【解决方案1】:

我最终使用Singleton 类使用ExecutorService 在单独的线程中进行加载/计算,然后让Handler 更新我的ViewHolder。不知道这是否是最好的方法,但到目前为止它工作没有任何问题。

private static class LazyLoadManager {
    private static LazyLoadManager INSTANCE;
    private final ExecutorService pool;
    private Map<ViewHolder, String> viewHolders = Collections.synchronizedMap(new WeakHashMap<ViewHolder, String>());
    private Context context;

    private LazyLoadManager(Context context) {
        this.context = context;
        pool = Executors.newFixedThreadPool(5);
    }

    public static LazyLoadManager getInstance(Context context) {
        if (INSTANCE == null) {
            INSTANCE = new LazyLoadManager(context.getApplicationContext());
        }
        return INSTANCE;
    }

    private void loadData(final ViewHolder viewHolder, final Model myModel) {

        // Put ViewHolder and respective tag into Map
        viewHolders.put(viewHolder, myModel.getTag());

        final Handler handler = new Handler(new Handler.Callback() {
            @Override
            public boolean handleMessage(Message msg) {

                // Get result object
                Model myResultModel = (Model) msg.obj;

                // Result was initialized
                if (myResultModel != null) {

                    // Get ViewHolder tag from map
                    String tag = viewHolders.get(viewHolder);

                    // Set ViewHolder content, if saved tag matches tag of this ViewHolder
                    if (tag != null && tag.equals(viewHolder.getTag())) {
                        viewHolder.viewA.setText(myResultModel.getThis());
                        viewHolder.viewB.setText(myResultModel.getThat());
                    }
                }
                return true;
            }
        });

        pool.submit(new Runnable() {
                        @Override
                        public void run() {
                            Model myResultModel = null;

                            if (myModel != null) {

                                // do required calculations and secondary queries based on myModel

                                myResultModel.setThis(result1);
                                myResultModel.setThat(result2);
                            }

                            Message message = Message.obtain();
                            message.obj = myResultModel;

                            handler.sendMessage(message);
                        }
                    }

        );
    }

在我的RecyclerViewonBindViewHolder 方法中,然后我像这样调用我的 LazyLoadManager

LazyLoadManager.getInstance(context).loadData(viewHolder, myModel);

【讨论】:

    猜你喜欢
    • 2020-04-21
    • 2013-12-25
    • 1970-01-01
    • 1970-01-01
    • 2021-01-06
    • 1970-01-01
    • 2013-10-20
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多