2017-01-19 73 views
0

我正在填充RecyclerView,最多可以輸入sqlite database的數千個條目,通過AsyncTaskLoader加載。該列表需要過濾,所以我需要一次加載所有條目。 RecyclerView的ViewHolders中的一些TextViews包含進一步的數據庫查詢結果(基於初始結果)或其他類型的計算。RecyclerView延遲加載TextView內容

將初始查詢擴展爲包含JOIN(至少會使輔助查詢過時)會減慢加載速度。但是,在RecyclerView的onBind方法內部執行查詢/計算,會使得流暢性低於沒有它們。

有沒有辦法爲這些計算的TextViews延遲加載內容?我搜索的例子,但像「畢加索」和「滑翔」只允許加載圖像...

任何幫助表示讚賞!

感謝, 羅布

+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); 
         } 
        } 

     ); 
    } 

以我RecyclerViewonBindViewHolder方法然後我打電話給我LazyLoadManager這樣

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