简体   繁体   中英

Android Recycler view adapter filter with animation

I am trying to optimize the filter method for RecyclerView Adapter in Android. The list is used as an ArrayList. I have seen this post but they are filtering from the original list every time.

Example: if there are 10 results for String 'a' then user type 'm' , 'am' results are subset of 'a' results(results.size()<=10).

I have three points to ask in this question,

  1. Can I optimize HashMap memory by using ArrayMap? Should I use comma separated positions in String instead of Integer objects array or any way to use int primitive array?
  2. I am not getting any animation in this result, how to get that? (I am using notifyItemInserted still no animation)
  3. How much data should be kept in Hashmap, till 2 characters or it should be according to result list size?
I would be glad to know if anything can be done better in this code other than these points.

In below code, mList is used in onBindViewHolder method. copyList always contains all data(no insertion or deletion is done on that).

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

Check this out https://medium.com/@iammert/using-diffutil-in-android-recyclerview-bdca8e4fbb00#.ehc0gaijt

DiffUtils is what are you looking for. You can use it in Rx chain to move it out of mainThread for a large data. here is a example https://medium.com/@nullthemall/diffutil-is-a-must-797502bc1149#.yg35y9q9b

要给出第二点的答案,你可以试试这个:

 notifyItemRangeChanged(pos, ItemList.size());
  1. HashMap is a Map, there are also TreeMap, LinkedHashMap and Hashtable. each of them has own features and interface is Map, not Collection. You can also use other data structures, like Treeset, HashSet, ArrayList, LinkedList and etc. These structures comes from Set and List interface, which extends to Collection interface. You can use each of them.

  2. If you insert any object to your collection, use notifyItemInserted(int position) , if you delete any object use notifyItemRemoved(int position) , if you update any object use notifyDataSetChanged() . Be careful about equality of your collection length and adapter view count.

  3. You can store parameter in maps how much you want. There is not any limitation. But you should choose best Collection for you, set, list or map.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM