Reputation: 241
I'm using RecyclerView and want to implement SearchView with it. I'm working since morning to get this but I'm unable to implement it as I want.
Problem:- When I search any item in RecyclerView then the list is updated correctly after that when I try to search another item then the list goes empty. I want that my list updated automatically on key press from the keyboard. I know there is lot of questions about it on SOF but I tried mostly all of them and I don't understand their code.
All these answers show that We should clear the list object but I cannot figure out how to get back the original list when anybody search any item.
There is my Adapter class:-
public class SongAdapter extends RecyclerView.Adapter<SongViewHolder> implements Filterable{
private Context context;
private List<SongObject> allSongs;
MyEditText options;
SongViewHolder songViewHolder;
View view;
PlaylistCounterDataSource dataSource;
DataSource fdataSource;
private List<SongObject> mFilteredList;
public SongAdapter(Context context, List<SongObject> allSongs) {
this.context = context;
this.allSongs = allSongs;
}
@Override
public SongViewHolder onCreateViewHolder(ViewGroup parent, final int viewType) {
view = LayoutInflater.from(context).inflate(R.layout.song_list_layout, parent, false);
options = view.findViewById(R.id.options);
return new SongViewHolder(view);
}
@Override
public void onBindViewHolder(final SongViewHolder holder, final int position) {
songViewHolder = holder;
holder.setIsRecyclable(false);
options.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
showOptions(view, position);
notifyDataSetChanged();
}
});
SongObject songs = allSongs.get(position);
holder.songTitle.setText(songs.getSongTitle());
holder.songAuthor.setText(songs.getSongAuthor());
Glide.with(context)
.load(songs.getSongCover())
.asBitmap()
.placeholder(R.drawable.default_art)
.error(R.drawable.default_art)
.override(200,200)
.fitCenter()
.diskCacheStrategy(DiskCacheStrategy.ALL)
.into(holder.songImage);
}
@Override
public int getItemCount() {
return allSongs.size();
}
@Override
public Filter getFilter() {
return new Filter() {
@Override
protected FilterResults performFiltering(CharSequence charSequence) {
String charString = charSequence.toString();
if (charString.isEmpty()) {
mFilteredList = allSongs;
}else {
List<SongObject> filteredList = new ArrayList<>();
for (SongObject androidVersion : allSongs) {
if (androidVersion.getSongTitle().toLowerCase().contains(charString) || androidVersion.getSongAuthor().toLowerCase().contains(charString)) {
filteredList.add(androidVersion);
}
}
mFilteredList = filteredList;
}
FilterResults filterResults = new FilterResults();
filterResults.values = mFilteredList;
Log.d("filter",""+filterResults.values);
return filterResults;
}
@Override
protected void publishResults(CharSequence charSequence, FilterResults filterResults) {
allSongs = (ArrayList<SongObject>) filterResults.values;
notifyDataSetChanged();
}
};
}
}
This is Fragment class :-
@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
inflater.inflate(R.menu.music_search, menu);
MenuItem searchItem = menu.findItem(R.id.music_search_bar);
SearchView searchView = (SearchView) searchItem.getActionView();
searchView.setQueryHint("Search Song");
searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
@Override
public boolean onQueryTextSubmit(String s) {
return false;
}
@Override
public boolean onQueryTextChange(String s) {
mAdapter.getFilter().filter(s);
/* s = s.toLowerCase();
ArrayList<SongObject> objects = new ArrayList<>();
for(SongObject so : objects){
String name = so.getSongTitle().toLowerCase();
if(name.contains(s))
objects.add(so);
}
mAdapter.filterList(objects);*/
return true;
}
super.onCreateOptionsMenu(menu, inflater);
}
In some answers they said regenerate recyclerView list when searching string's length is equals to 0. but what happens if there is more item with the same starting letter like:- ABC ADD ADU and it never equals to 0.
Upvotes: 3
Views: 2368
Reputation: 199
// this is wrong
@Override
public int getItemCount() {
return allSongs.size();
}
// use this
@Override
public int getItemCount() {
return filteredList.size();
}
in the initial state add all songs to the filteredSongs list then when user query clear the filteredList and add the result to it
Upvotes: 2