'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 |
