2017-01-19 6 views
0

Я заполняю RecyclerView до нескольких тысяч записей от sqlite database, загруженных через AsyncTaskLoader. Список должен быть фильтруемым, поэтому мне необходимо загрузить все записи за раз. Некоторые из TextViews в ViewHolders RecyclerView содержат результаты дальнейших запросов БД (на основе исходного результата) или других типов вычислений.RecyclerView lazy loading TextView content

Развернуть исходный запрос, чтобы включить JOINs (что, по крайней мере, сделало бы вторичные запросы устаревшими) действительно замедляет загрузку. Однако выполнение запросов/вычислений внутри метода onBind в RecyclerView делает flinging гораздо менее свободно, чем без них.

Есть ли способ сделать ленивую загрузку контента для этих вычислений TextViews? Я искал примеры, но библиотеки, такие как «Picasso» и «Glide», позволяют загружать изображения ...

Любая помощь оценивается!

Спасибо, Роб

+0

использования [это] (https://gist.github.com/Shywim/127f207e7248fe48400b) адаптер – pskink

+0

@pskink : Спасибо, но этот адаптер не очень подходит моим потребностям ... – user1905169

+0

просто используйте JOINS, и нет, для фильтрации вам не нужно загружать сразу все записи, просто переопределите 'runQueryOnBackgroundThread' или настройте его' FilterQueryProvider' – pskink

ответ

0

Я в конечном итоге, используя 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); 
         } 
        } 

     ); 
    } 

В onBindViewHolder методе моего RecyclerView я тогда называть мой LazyLoadManager как этот

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