0

I have a RecyclerView thats populated from my Firebase Database. The list is quite long so I want the user to be able to search the list. But when the user types the first character into the SearchView, nothing at all is returned.

This is the onCreateView in my FavouriteFragment UPDATED

  @Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, Bundle savedInstanceState){
    View view = inflater.inflate(R.layout.fragment_favourites, container, false);

    mAuth = FirebaseAuth.getInstance();
    current_user_id = mAuth.getCurrentUser().getUid();

    recyclerView = (RecyclerView) view.findViewById(R.id.route_favourites);
    RecyclerView.LayoutManager layoutManager = new LinearLayoutManager(getActivity());
    recyclerView.setLayoutManager(layoutManager);
    search = (SearchView) view.findViewById(R.id.search);

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

        @Override
        public boolean onQueryTextChange(String newText) {
            DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference().child("BusRoute");
            rootRef.addValueEventListener(new ValueEventListener() {
                @Override
                public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
                    for(DataSnapshot datasnapshot : dataSnapshot.getChildren()){
                        String key = datasnapshot.getKey();

                        Query query = rootRef.child(key).orderByChild("route").equalTo(newText);
                        query.addValueEventListener(new ValueEventListener() {
                            @Override
                            public void onDataChange(@NonNull DataSnapshot dataSnapshot) {

                                favouritesAdapter.notifyDataSetChanged();

                            }

                            @Override
                            public void onCancelled(@NonNull DatabaseError databaseError) {

                            }
                        });
                    }

                }

                @Override
                public void onCancelled(@NonNull DatabaseError databaseError) {

                }
            });

            return true;
        }
    });

    favouritesAdapter = new FavouritesAdapter(getDataSetHistory(), getActivity());
    favouritesAdapter.notifyDataSetChanged();
    recyclerView.setAdapter(favouritesAdapter);

    getBusRoutes();
    return view;
}

This is my favouritesAdapter:

public class FavouritesAdapter extends RecyclerView.Adapter<FavouritesAdapter.ViewHolder> implements Filterable {
    private List<BusRoute> favourites;
    private List<BusRoute> searchList;
    private Context context;

    public static class ViewHolder extends RecyclerView.ViewHolder{
        TextView routeTextView, originTextView, destinationTextView;
        ImageView addFavouritesButton;

        ViewHolder(View v){
            super(v);
            this.routeTextView = v.findViewById(R.id.route);
            this.destinationTextView = v.findViewById(R.id.destination);
            this.originTextView = v.findViewById(R.id.origin);
            this.addFavouritesButton = v.findViewById(R.id.addToFavourites);
            addFavouritesButton.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    String route = routeTextView.getText().toString();
                    System.out.println("clicked");
                    System.out.println(route);
                    //addToFavourites(route);
                }
            });
        }

    @NonNull
    @Override
    public FavouritesAdapter.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int i) {
       View view = LayoutInflater.from(context).inflate(R.layout.favourite_card, parent, false);

       return new FavouritesAdapter.ViewHolder(view);
    }

    @Override
    public void onBindViewHolder(@NonNull FavouritesAdapter.ViewHolder viewHolder, int i) {
        BusRoute bus = favourites.get(i);
        viewHolder.originTextView.setText(String.valueOf(bus.getOrigin()));
        viewHolder.destinationTextView.setText(String.valueOf(bus.getDestination()));
        viewHolder.routeTextView.setText(String.valueOf(bus.getRoute()));
    }

    public FavouritesAdapter(ArrayList<BusRoute> favourites, Context context){
        this.context = context;
        this.favourites = favourites;
        searchList = new ArrayList<>(favourites);
    }

    @Override
    public int getItemCount() {
        System.out.println(favourites);
        return favourites.size();
    }

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

    private Filter favouriteFilter = new Filter(){

        @Override
        protected FilterResults performFiltering(CharSequence constraint) {
            System.out.println("filter results");
           List<BusRoute> filteredList = new ArrayList<>();
           if(constraint==null || constraint.length()==0){
               filteredList.addAll(searchList);
           }else{
               String filterPattern = constraint.toString().toLowerCase().trim();

               for(BusRoute br : searchList){
                   if(br.getRoute().toLowerCase().contains(filterPattern)){
                       filteredList.add(br);
                   }else{
                       System.out.println("nothing here");
                   }
               }
           }
            System.out.println("set filter results");
           FilterResults results = new FilterResults();
           results.values = filteredList;
           return results;
        }

        @Override
        protected void publishResults(CharSequence constraint, FilterResults results) {
            favourites.clear();
            favourites.addAll((List)results.values);
            notifyDataSetChanged();
        }
    };
}

I just want to have a filterable search bar but cannot get it working! I'd appreciate any help at all!

evelcon
  • 43
  • 7
  • 1
    Check **[this](https://stackoverflow.com/questions/50682046/applying-word-stemming-in-searchview-for-fetch-data-from-firebase-database/50682657)** out. – Alex Mamo Jun 03 '19 at 13:13
  • Thanks for the reply! Does this work with the SearchView? And if so should it be done in the onQueryTextChange? – evelcon Jun 03 '19 at 14:52
  • Yes iti does work. Yes, inside the `onQueryTextChange`. Does it work? – Alex Mamo Jun 03 '19 at 15:09
  • From debugging I can see I am accessing the right information from the database but I cannot seem to update the adapter to display the results that I want. I updated my code do you mind taking a look? – evelcon Jun 03 '19 at 16:22

2 Answers2

0

In publish results method. Don't clear your array list. That is the reason for empty data

Mohit patel
  • 296
  • 1
  • 8
  • But the next line is adding back the filtered values. When I remove it, and enter a character, the full list is still there but no filter applied, so it still doesn't work – evelcon Jun 03 '19 at 12:44
0
Try this   
@Override
public Filter getFilter() {
    return new Filter() {
        @Override
        protected FilterResults performFiltering(CharSequence charSequence) {
            String query = charSequence.toString();

            List<String> filtered = new ArrayList<>();

            if (query.isEmpty()) {
                filtered = items;
            } else {
                for (String movie : items) {
                    if (movie.toLowerCase().contains(query.toLowerCase())) {
                        filtered.add(movie);
                    }
                }
            }

            FilterResults results = new FilterResults();
            results.count = filtered.size();
            results.values = filtered;
            return results;
        }
Mohit patel
  • 296
  • 1
  • 8