使用动画的Android Recycler视图适配器筛选器

7
我正在尝试优化Android中RecyclerView Adapter的过滤方法。该列表作为ArrayList使用。我看到了这个post,但他们每次都从原始列表进行过滤。
例如:如果有10个字符串'a'的结果,那么用户输入'm','am'的结果是'a'结果的子集(results.size()<=10)。
我在这个问题中有三个要点要问,
  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++);
            }
        }
    }

检查我的答案,DiffUtils 是你要找的。 - wojciech_maciejewski
这两个问题,我能否通过使用ArrayMap来优化HashMap的内存?我应该使用逗号分隔的字符串位置而不是整数对象数组,或者有没有使用int原始数组的方法?在HashMap中应该保留多少数据,直到2个字符还是根据结果列表大小? - Harish Gyanani
@wojciech_maciejewski,您的回答很有用,我已经点了赞。但它并没有完全回答问题。 - Harish Gyanani
3个回答

4

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. 您可以在地图中存储多少个参数。没有任何限制。但是您应该为自己选择最佳的Collection,set、list或map。


1
为了回答你的第二点,你可以尝试这样做:
 notifyItemRangeChanged(pos, ItemList.size());

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接