web-dev-qa-db-fra.com

Ajouter un filtre de recherche sur RecyclerView avec cartes?

J'ai trouvé des solutions pour les filtres sur ListView et SearchView sur RecyclerView séparément, mais je souhaite les combiner. Est-ce même possible?

20
priyank

Oui, c'est possible Votre RecyclerView.Adapter Peut implémenter Filterable. Après cela, vous devez remplacer la méthode Filter getFilter().

Vous devez définir votre propre filtre comme indiqué dans le code ci-dessous:

@Override
public Filter getFilter() {
    return new YourFilterClass();
}

YourFilterClass

class YourFilterClass extends Filter {

        @Override
        protected FilterResults performFiltering(CharSequence constraint) {
            //Here you have to implement filtering way
            final FilterResults results = new FilterResults();
            //logic to filtering
            results.values = ...
            results.count = ...
            return results;
        }

        @Override
        protected void publishResults(CharSequence constraint, FilterResults results) {
            // here you can use result - (f.e. set in in adapter list)
        }
}

Exemple

public class UserListAdapter extends RecyclerView.Adapter<UserListAdapter.ViewHolder> implements Filterable {

    private final List<User> userList;

    private final List<User> filteredUserList;

    private UserFilter userFilter;

    public UserListAdapter(Context context) {
        this.userList =new ArrayList<>();
        this.filteredUserList = new ArrayList<>();
    }


    ///... other methods

    @Override
    public Filter getFilter() {
       if(userFilter == null)
             userFilter = new UserFilter(this, userList);
        return userFilter;
    }

    private static class UserFilter extends Filter {

        private final UserListAdapter adapter;

        private final List<User> originalList;

        private final List<User> filteredList;

        private UserFilter(UserListAdapter adapter, List<User> originalList) {
            super();
            this.adapter = adapter;
            this.originalList = new LinkedList<>(originalList);
            this.filteredList = new ArrayList<>();
        }

        @Override
        protected FilterResults performFiltering(CharSequence constraint) {
            filteredList.clear();
            final FilterResults results = new FilterResults();

            if (constraint.length() == 0) {
                filteredList.addAll(originalList);
            } else {
                final String filterPattern = constraint.toString().toLowerCase().trim();

                for (final User user : originalList) {
                    if (user.getName().contains(filterPattern)) {
                        filteredList.add(user);
                    }
                }
            }
            results.values = filteredList;
            results.count = filteredList.size();
            return results;
        }

        @Override
        protected void publishResults(CharSequence constraint, FilterResults results) {
            adapter.filteredUserList.clear();
            adapter.filteredUserList.addAll((ArrayList<User>) results.values);
            adapter.notifyDataSetChanged();
        }
    }
}

Après cela, à l'endroit où vous souhaitez filtrer l'appel:

userListAdapter.getFilter().filter(text)
79
Konrad Krakowiak

À l'intérieur Fragment Class déclare que:

protected List<User> mDataset;
protected List<User> mDataOrigin;

puis à l'intérieur de onCreate ajoutez la même destination source aux deux dataSet ant dataOrigin

mDataset = getObjectsFromDB();
mDataOrigin = getObjectsFromDB();

Enfin, utilisez la fonction magique:

private void filterRecyclerView(String charText){
    charText = charText.toLowerCase();
    clearDataSet();
    if (charText.length() == 0) {
        mDataset.addAll(mDataOrigin);
    } else {
        for (User user : mDataOrigin) {
            if (user.getName().toLowerCase().contains(charText)) {
                mDataset.add(user);
            }
        }
    }
    mAdapter.notifyDataSetChanged();
}

Remarque User est le contenu de la liste que vous pouvez remplacer par votre objet amusez-vous :)

2
Mostafa Anter

Voici un exemple de code complet

Classe de modèle

public class Skills {

    int id;
    String skill;
    boolean isSelected;

    public boolean isSelected() {
        return isSelected;
    }

    public void setSelected(boolean selected) {
        isSelected = selected;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getSkill() {
        return skill;
    }

    public void setSkill(String skill) {
        this.skill = skill;
    }
}

Classe d'adaptateur

private static final String TAG = SkillAdapter.class.getSimpleName();
    protected List<Skills> mOriginalData = new ArrayList<>();
    protected List<Skills> mResultData = new ArrayList<>();

    protected Activity mActivity;
    OnRecyclerViewClick onRecyclerViewClick;
    private ItemFilter mFilter = new ItemFilter();

    public SkillAdapter(Activity activity, OnRecyclerViewClick onRecyclerViewClick) {
        mActivity = activity;
        this.onRecyclerViewClick = onRecyclerViewClick;
    }

    @Override
    public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {

        View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_skill,
                parent, false);

        return new ViewHolder(view);
    }

    @Override
    public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {

        final Skills data = mResultData.get(position);
        try {
            final ViewHolder viewHolder = (ViewHolder) holder;

            if (data != null) {
                viewHolder.checkSkill.setText(data.getSkill());
                viewHolder.checkSkill.setChecked(data.isSelected());
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Override
    public int getItemCount() {
        return mResultData.size();
    }

    public void addItem(Skills exam) {
        mOriginalData.add(exam);
        mResultData.add(exam);
        int index = mOriginalData.indexOf(exam);
        notifyItemInserted(index);
    }

    public void removeItem(int index) {
        mOriginalData.remove(index);
        notifyItemRemoved(index);
    }

    public void removeItem(Skills exam) {
        int index = mOriginalData.indexOf(exam);
        mOriginalData.remove(exam);
        notifyItemRemoved(index);
    }

    public Filter getFilter() {
        return mFilter;
    }


    public Skills getItem(int index) {
        return mOriginalData.get(index);
    }

    public void replaceItem(int index, Skills audioMeta) {
        mOriginalData.set(index, audioMeta);
        notifyItemChanged(index);
    }

    public class ViewHolder extends RecyclerView.ViewHolder {

        CheckBox checkSkill;

        public ViewHolder(View itemView) {
            super(itemView);

            checkSkill = (CheckBox) itemView.findViewById(R.id.chkSkill);
            checkSkill.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    onRecyclerViewClick.onItemClick(v, getLayoutPosition());
                }
            });
        }
    }


    private class ItemFilter extends Filter {

        @Override
        protected FilterResults performFiltering(CharSequence constraint) {

            String filterString = constraint.toString().toLowerCase();

            FilterResults results = new FilterResults();

            int count = mOriginalData.size();

            final ArrayList<Skills> tempFilterList = new ArrayList<Skills>(count);

            String filterableString;

            for (int i = 0; i < count; i++) {
                filterableString = mOriginalData.get(i).getSkill();
                if (filterableString.toLowerCase().contains(filterString)) {
                    tempFilterList.add(mOriginalData.get(i));
                }
            }

            results.values = tempFilterList;
            results.count = tempFilterList.size();

            return results;
        }

        @SuppressWarnings("unchecked")
        @Override
        protected void publishResults(CharSequence constraint, FilterResults results) {
            mResultData.clear();
            mResultData = (ArrayList<Skills>) results.values;
            notifyDataSetChanged();
        }
    }

En cours d'utilisation

    mAdapter = new SkillAdapter(SkillsActivity.this, SkillsActivity.this);
    recyclerView.setLayoutManager(new LinearLayoutManager(mContext));
    recyclerView.setAdapter(mAdapter);

puis filtre

editSearch.addTextChangedListener(new TextWatcher() {
        @Override
        public void beforeTextChanged(CharSequence s, int start, int count, int after) {

        }

        @Override
        public void onTextChanged(CharSequence s, int start, int before, int count) {

        }

        @Override
        public void afterTextChanged(Editable s) {
            mAdapter.getFilter().filter(editSearch.getText().toString());
        }
    });
2
user2837615