'How to filter RecyclerView inside a Fragment using SearchView

I'm just new to Android and have to build an App using MVVM and Fragments. I have my Recyclerview within Basefragment and i want to filter it using SearchView. When I type something on it, it doesn't filter the list (nothing happens).

If someone could solve it, then I would be really very thankful.

Basefragment

public class BaseFragment extends Fragment implements CarAdapterEvent, SearchView.OnQueryTextListener {

    private RecyclerView recyclerView;
    private RecyclerView.LayoutManager layoutManager;
    private ArrayList<Car>list=new ArrayList<>();
    private MyViewModel myViewModel;
    public RecyclerAdapter recyclerAdapter;

    // Required empty public constructor
    public BaseFragment() { }

    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
    }
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
    {
        setHasOptionsMenu(true);
        // Inflate the layout for this fragment
        View view= inflater.inflate(R.layout.fragment_base, container, false);
        //Inflate recyclerView
        recyclerView=view.findViewById(R.id.recyclerViewId);
        // define and set LayoutManager
        layoutManager= new GridLayoutManager(requireActivity(),2);
        recyclerView.setLayoutManager(layoutManager);
        //define and set RecyclerView Adapter
        recyclerAdapter = new RecyclerAdapter(list, getContext(),this);
        recyclerView.setAdapter(recyclerAdapter);
        //observer
        myViewModel= new ViewModelProvider(this).get(MyViewModel.class);
        myViewModel.getGetAllCars().observe(getViewLifecycleOwner(), new Observer<List<Car>>() {
           @Override
           public void onChanged(List<Car> cars) {
               recyclerAdapter.setData(cars);
           }
       });
        return view;
    }
    @Override
    public void onCreateOptionsMenu(@NonNull Menu menu, @NonNull MenuInflater inflater) {
        inflater = getActivity().getMenuInflater();
        inflater.inflate(R.menu.search_menu, menu);
        MenuItem searchItem = menu.findItem(R.id.action_search);
        SearchView searchView = (SearchView)  searchItem.getActionView();
        searchView.setOnQueryTextListener(this);
    }
    @Override
    public boolean onQueryTextSubmit(String query) {
        return true;
    }
    @Override
    public boolean onQueryTextChange(String newText) {
        if (newText == null || newText.trim().isEmpty()){
            recyclerAdapter.setFilter(list);
            return false;
        }
        newText= newText.toLowerCase();
        ArrayList<Car> filteredList = new ArrayList<>();
        for (Car carItem : list){
            if (carItem.getCarModel().toLowerCase().contains(newText)){
                filteredList.add(carItem);
            }
        }
        recyclerAdapter.setFilter(filteredList);
        return true;
    }
    @Override
    public void onDeleteClicked(Car car) {
      myViewModel.deleteCar(car);
      MainActivity.fragmentManager.beginTransaction().replace(R.id.container,new BaseFragment(),null).commit();
    }
    @Override
    public void onUpdateClicked(Car car) {
        myViewModel.updateCar(car);
        MainActivity.fragmentManager.beginTransaction().replace(R.id.container,new UpdateFragment(),null).commit();
    }


}

Adapter

public class RecyclerAdapter extends RecyclerView.Adapter<RecyclerAdapter.MyViewHolder> {

   private List<Car>list;
   private List<Car> listFull;
   private Context context;
   private MyViewModel myViewModel;
   private CarAdapterEvent carAdapterEvent;
   //Constructor
    public RecyclerAdapter(List<Car> list,Context context,CarAdapterEvent carAdapterEvent ) {
        this.list = list;
        this.context=context;
        this.carAdapterEvent=carAdapterEvent;
    }
    // make a copy of list tu use it later for filter recyclerView
    public RecyclerAdapter(List<Car> list) {
        this.list = list;
        listFull = new ArrayList<>(list);
    }

    @NonNull
    @Override
    public MyViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.car_item,parent,false);
        MyViewHolder myViewHolder = new MyViewHolder(view);
        context=parent.getContext();
        return myViewHolder;
    }
    @Override
    public void onBindViewHolder(@NonNull MyViewHolder holder, int position) {
        Car car = list.get(position);
        holder.tvModel.setText(car.getCarModel());
        holder.tvColor.setText(car.getCarColor());
        holder.tvDpl.setText(car.getCarDpl());
        holder.tvDescription.setText(car.getCarDescription());
        holder.tvPrice.setText(car.getCarPrice());
    }
    @Override
    public int getItemCount() {
        if(list !=null)
        {
            return list.size();
        }
        else return 0;
    }
   public void setData(List<Car>list){
       this.list=list;
       notifyDataSetChanged();
   }
    public  void setFilter(ArrayList<Car> carList){
        carList.clear();
        carList.addAll(carList);
        notifyDataSetChanged();
    }

    // generate ViewHolder
    public class MyViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
        TextView tvModel;
        TextView tvColor;
        TextView tvDpl;
        TextView tvDescription;
        TextView tvPrice;
        Button btnDelete;
        Button updateButtonOnRecyclerView;
        // Constructor of ViewHolder
        public MyViewHolder(@NonNull View itemView) {
            super(itemView);
            // Inflate the views
            tvModel=itemView.findViewById(R.id.model);
            tvColor=itemView.findViewById(R.id.color);
            tvDescription=itemView.findViewById(R.id.description);
            tvDpl=itemView.findViewById(R.id.dpl);
            tvPrice=itemView.findViewById(R.id.price);
            btnDelete=itemView.findViewById(R.id.btn_delete);
            updateButtonOnRecyclerView =itemView.findViewById(R.id.btn_update);

            // Listener for Delete button
            btnDelete.setOnClickListener(this);
            btnDelete.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    int position = getAdapterPosition();
                    carAdapterEvent.onDeleteClicked(list.get(position));
                }
            });
            //Listener for update button
            updateButtonOnRecyclerView.setOnClickListener(this);
            updateButtonOnRecyclerView.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    int position = getAdapterPosition();
                    carAdapterEvent.onUpdateClicked(list.get(position));
                }
            });
        }
       private void CreateAlertDialoge()
       {
           AlertDialog.Builder builder =new AlertDialog.Builder(context);
           builder.setMessage("Are you sure to delete");
           builder.setPositiveButton("Yes", new DialogInterface.OnClickListener() {
               @Override
               public void onClick(DialogInterface dialog, int which) {

                   Car car = new Car();
                   int ID=list.get(getAdapterPosition()).getCarId();
                   car.setCarId(ID);


                  myViewModel.deleteCar(car);


                   MainActivity.fragmentManager.beginTransaction().replace(R.id.container,new BaseFragment(),null).commit();

                   Toast.makeText(context, "Yes", Toast.LENGTH_SHORT).show();
               }
           });
           builder.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
               @Override
               public void onClick(DialogInterface dialog, int which) {
                   Toast.makeText(context, "no", Toast.LENGTH_SHORT).show();

               }
           });
           builder.create();
           builder.show();
       }
        @Override
        public void onClick(View v) { }
    }

MainActivity

public class MainActivity extends AppCompatActivity {

    public static FragmentManager fragmentManager;
     static RoomDatabase roomDatabase;
     private BottomNavigationView bottomNavigationView;

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        return true;
    }
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        bottomNavigationView=findViewById(R.id.bottom_nav);
        bottomNavigationView.setOnNavigationItemSelectedListener(bottomNavMethod);
        if (savedInstanceState != null) {
            // replace fragment
           // getSupportFragmentManager().beginTransaction().replace(R.id.container,new BaseFragment()).commit();
            FragmentManager fragmentManager = getSupportFragmentManager();
            FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
            // make an instance of BaseFragment
            BaseFragment baseFragment=new BaseFragment();
            fragmentTransaction.replace(R.id.container,baseFragment)
                    .addToBackStack(null).commit();
        }
        //for manager
        fragmentManager=getSupportFragmentManager();
        roomDatabase= Room.databaseBuilder(getApplicationContext(), RoomDatabase.class,
                "mydb").allowMainThreadQueries()
                .build();

       if (findViewById(R.id.container)!=null)
       {
           if(savedInstanceState!=null)
           {
               return;
           }
       }
        fragmentManager.beginTransaction().add(R.id.container,
                new BaseFragment(),null).commit();
    }

    private BottomNavigationView.OnNavigationItemSelectedListener bottomNavMethod= new BottomNavigationView.OnNavigationItemSelectedListener() {
        @Override
        public boolean onNavigationItemSelected(@NonNull MenuItem item) {
            Fragment fragment=null;
            switch (item.getItemId())
            {
                case R.id.base_fragment_id:
                    fragment=new BaseFragment();
                    break;
                case R.id.input:
                    fragment=new AddCarFragment();
                    break;
                case R.id.settings:
                    fragment=new SettingsFragment();
                    break;
            }
            getSupportFragmentManager().beginTransaction().replace(R.id.container,fragment).commit();
            return true;
        }
    };


Solution 1:[1]

Have you implemented Filterable on recycleview adapter ? I guess, you haven't try moving the filter code you did, onto the overridden method of filterable. you can try this tutorial for further knowledge

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Vivek Gupta