6

我正嘗試優化Android中RecyclerView適配器的篩選器方法。該列表用作ArrayList。我看過這個post,但他們每次都從原始列表中過濾。例如:如果String'a'有10個結果,那麼用戶類型'm','am'結果是'a'結果的子集(results.size()< = 10)。帶動畫的Android Recycler視圖適配器篩選器

我在這個問題中有三點要問,

  1. 我可以使用ArrayMap優化HashMap內存嗎?我應該使用逗號分隔位置在字符串而不是整數對象數組或任何方式來使用int基本數組?
  2. 我沒有在這個結果中得到任何動畫,如何得到它? (我正在使用notifyItemInserted仍然沒有動畫)
  3. 應該在Hashmap中保留多少數據,直到2個字符或它應該根據結果列表大小?
我很高興知道這些代碼以外的任何事情可以做得更好。

在下面的代碼中,mList用於onBindViewHolder方法。 copyList始終包含所有數據(不會插入或刪除)。

class MyFilter extends Filter { 


     /** 
     * 1. check do we have search results available (check map has this key) 
     * 2. if available, remove all rows and add only those which are value for that key (string) 
     * 3. else check do we have any key available starting like this, s=har, already available -ha then it can be reused 
     * 
     * @param constraint 
     */ 
     @Override 
     protected FilterResults performFiltering(CharSequence constraint) { 
      //Here you have to implement filtering way 
      final FilterResults results = new FilterResults(); 

      if (!mSearchMap.containsKey(constraint.toString())) { 
       String supersetKey = getSupersetIfAvailable(mSearchMap, constraint.toString()); 
       if (supersetKey == null) { 
        List<Integer> foundPositions = doFullSearch(copyList, constraint.toString()); 
        mSearchMap.put(constraint.toString(), foundPositions); 
       } else { 
        List<Integer> foundPositions = filterFromSuperset(copyList, mSearchMap.get(supersetKey), constraint.toString()); 
        mSearchMap.put(constraint.toString(), foundPositions); 
       } 
      } 


      return results; 
     } 

     private String getSupersetIfAvailable(Map<String, List<Integer>> mSearchMap, String s) { 
      Set<String> set = mSearchMap.keySet(); 
      List<String> list = new ArrayList<>(set); 
      Collections.sort(list); 
      Collections.reverse(list); 
      for (String c : list) { 
       if (s.startsWith(c)) { 
        return c; 
       } 
      } 
      return null; 
     } 
     private List<Integer> filterFromSuperset(List<WeekWorkBean> list, List<Integer> supersetResults, String s) { 
      List<Integer> results = new ArrayList<>(); 
      String lowerS = s.toLowerCase(); 
      for (int i = 0; i < supersetResults.size(); i++) { 
       if (list.get(supersetResults.get(i)).getEmpName().toLowerCase().startsWith(lowerS)) { 
        results.add(supersetResults.get(i)); 
       } 
      } 
      return results; 
     } 

     private List<Integer> doFullSearch(List<WeekWorkBean> list, String s) { 
      List<Integer> results = new ArrayList<>(); 
      for (int i = 0; i < list.size(); i++) { 
       if (list.get(i).getEmpName().toLowerCase().startsWith(s.toLowerCase())) { 
        results.add(i); 
       } 
      } 
      return results; 
     } 

     @Override 
     protected void publishResults(CharSequence constraint, FilterResults results) { 
      // here you can use result - (f.e. set in in adapter list) 
      mList.clear(); 
      notifyDataSetChanged(); 
      List<Integer> res = mSearchMap.get(constraint.toString()); 
      int j = 0; 
      for (Integer i : res) { 
       mList.add(copyList.get(i)); 
       notifyItemInserted(j++); 
      } 
     } 
    } 
+0

檢查我的答案,DiffUtils是你在找什麼 –

+0

和這兩點,我可以使用ArrayMap優化HashMap內存嗎?我應該使用逗號分隔位置在字符串而不是整數對象數組或任何方式來使用int基本數組? 應該在Hashmap中保留多少數據,直到2個字符或它應該根據結果列表大小? –

+0

@wojciech_maciejewski你的答案是有用的,我已經給了upvote。但它沒有回答完整的問題 –

回答

1

爲了讓你的第二點的答案你可以試試這個:

notifyItemRangeChanged(pos, ItemList.size()); 
1
  1. 的HashMap是Map,也有TreeMap中,LinkedHashMap的和Hashtable。他們每個人都有自己的功能,界面是Map,而不是Collection。您還可以使用其他數據結構,如Treeset,HashSet,ArrayList,LinkedList等。這些結構來自Set和List接口,它擴展到Collection接口。你可以使用它們中的每一個。

  2. 如果插入任何對象到您的收藏,使用notifyItemInserted(int position),如果你刪除任何對象使用notifyItemRemoved(int position),如果您更新任何對象使用notifyDataSetChanged()。小心收集長度和適配器查看次數的平等。

  3. 您可以在地圖中存儲參數多少你想要的。沒有任何限制。但你應該爲你選擇最好的收藏集,設置,列表或地圖。