0

I'm looking for a way to filter my data in a RecyclerView without the state of a given view affects another view when filter is applied. Pratically, I have this problem : 1. I add "Martins" to my friend list by clicking on the add button (image msSxq.png) list without filter enter image description here

  1. I perform a search and I get this (image FGSwF.png): list after performing searching action enter image description here

It'is then clear that, as the seraching action is done, my list content change and then the new items take old items place and take old items button state !

I'm looking for a way to avoid this. I tried to read several post on similar subject but nothing (Example of link : How to filter a RecyclerView with a SearchView)

Thank you for your helps !

Edit : 07/02/2020 - onBindViewHolder and Filtering Code

onBindViewHolder (in my Custom Adapter)

@Override
public void onBindViewHolder(@NonNull final FriendAdapterViewHolder holder, int position) {
    String mUsernameString = suggestionList.get(position);
    String mModUsernameString = suggestionList.get(position) + "_@chatter";

    holder.username.setText(mUsernameString);
    holder.mod_username.setText(mModUsernameString);

}

Filtering methods (always in my Adapter)

@Override
public Filter getFilter() {
    return friendFilter;
}

private Filter friendFilter = new Filter() {
    @Override
    protected FilterResults performFiltering(CharSequence constraint) {
        ArrayList<String> listFiltered = new ArrayList<>();

        if (fullSuggestionList != null) {
            if (constraint == null || constraint.length() == 0) {
                listFiltered.addAll(fullSuggestionList);
            } else {
                String searchTextLowerCase = constraint.toString().toLowerCase().trim();
                for (String item : fullSuggestionList) {
                    if (item.toLowerCase().contains(searchTextLowerCase)) {
                        listFiltered.add(item);
                    }
                }
            }

            FilterResults results = new FilterResults();
            results.values = listFiltered;

            return results;
        } else {
            return null;
        }

    }

    @Override
    protected void publishResults(CharSequence constraint, FilterResults results) {
        if(results.values != null) {
            suggestionList.clear();
            suggestionList.addAll((ArrayList<String>) results.values);
            notifyDataSetChanged();
        }
    }
};

And finally, in my Activity where I perform searching action

searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
        @Override
        public boolean onQueryTextSubmit(String query) {
            return false;
        }

        @Override
        public boolean onQueryTextChange(String newText) {
            if (adapter.getCompleteItemList() != null) {
                adapter.getFilter().filter(newText);
            }
            return false;
        }
    });
narutoArea51
  • 141
  • 11

1 Answers1

0

Finally, I tried to understand deeply how recyclerview works and I found a solution that works perfectly. In fact, when we're filtering data in a searchview linked to a recyclerview, the last one, when it's not neccessary, recycles already created view and change simply its content. To avoid that, we have to create a unique identifier for each view created and tell to our recyclerview have unique view Ids. Pratically, I did those things :

In my data model, I create a method that generate a unique Id for each instance created a little bite like this :

public class MyDataModel {
    private long mId;
    ...//others variables here

    private long computeId(.../*some parameters if needed*/) {
        // write code here to generate your unique code
        return result;
    }

    public long getmId() {
        return this.mId;
    }

In my Adapter, then, I override the getItemId() method

@override public long getItemId(int position) {
    return myDataList.get(position).getmId();
}

And, always in my Adapter, in its constructor I add this line of code :

this.setHasStableIds(true);

That's all !

narutoArea51
  • 141
  • 11