web-dev-qa-db-ja.com

カード付きのRecyclerViewに検索フィルターを追加しますか?

ListView上のフィルターとSearchView上のRecyclerViewのフィルターのソリューションを別々に見つけましたが、それらを組み合わせたいと思います。それも可能ですか?

20
priyank

はい、可能です_RecyclerView.Adapter_はFilterableを実装できます。その後、Filter getFilter()メソッドをオーバーライドする必要があります。

以下のコードに示すように、独自のフィルターを定義する必要があります。

_@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)
        }
}
_

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

その後、コールをフィルタリングする場所で:

_userListAdapter.getFilter().filter(text)
_
79

内部Fragment Class宣言する:

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

次に、onCreate内で同じソース宛先をdataSetとdataOriginの両方に追加します

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

最後に、マジック関数を使用します。

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

Userは、オブジェクトで置き換えることができるリストコンテンツであることに注意してください:)

2
Mostafa Anter

ここに完全なサンプルコードがあります

モデルクラス

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

アダプタクラス

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

活動中

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

その後フィルター

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