SearchView doesn´t filter items - java

Unfortunately, my SeachView does not work. No errors are shown in Android Studio and my app works without any problems. My problem is that when I enter something into the SearchView nothing happens. The Recyclerview still shows all items from my Array List and does not filter them.
Thanks for all the answers :)
Main Activity:
public class MainActivity extends AppCompatActivity {
private RecyclerView recyclerView;
private ArrayList<Mountain> list;
private SearchView searchView;
private ItemCardViewAdapter mAdapter;
private RecyclerView.LayoutManager mLayoutManager;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
recyclerView = findViewById(R.id.recycler_view);
recyclerView.setHasFixedSize(true);
list = new ArrayList<>();
list.addAll(MountainData.getListData());
showRecyclerViewList();
mAdapter = new ItemCardViewAdapter(this);
mAdapter.setListMountain(list);
searchView = (SearchView) findViewById(R.id.searchView);
searchView.setQueryHint("Search View");
searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
#Override
public boolean onQueryTextSubmit(String query) {
mAdapter.getFilter().filter(query);
return false;
}
#Override
public boolean onQueryTextChange(String query) {
mAdapter.getFilter().filter(query);
return false;
}
});
}
private void showRecyclerViewList() {
recyclerView = findViewById(R.id.recycler_view);
recyclerView.setHasFixedSize(true);
mLayoutManager = new LinearLayoutManager(this);
ItemCardViewAdapter cardViewAdapter = new ItemCardViewAdapter(this);
cardViewAdapter.setListMountain(list);
recyclerView.setLayoutManager(mLayoutManager);
recyclerView.setAdapter(cardViewAdapter);
}
Adapter:
public class ItemCardViewAdapter extends RecyclerView.Adapter<ItemCardViewAdapter.CardViewHolder> implements Filterable {
private Context context;
private ArrayList<Mountain> listMountain;
private ArrayList<Mountain> filteredList = new ArrayList<>();
public ItemCardViewAdapter(MainActivity context) {
this.context = context;
}
public ArrayList<Mountain> getListMountain() {
return listMountain;
}
public void setListMountain(ArrayList<Mountain> listMountain) {
this.listMountain = listMountain;
}
#NonNull
#Override
public CardViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_cardview, parent, false);
return new CardViewHolder(view);
}
#Override
public void onBindViewHolder(#NonNull CardViewHolder holder, final int position) {
holder.tvName.setText(getListMountain().get(position).getName());
holder.tvDescription.setText(getListMountain().get(position).getDescription());
Glide.with(context).load(getListMountain().get(position).getPhoto()).into(holder.imgPhoto);
// intent parcel able to detail
holder.button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent detailActivity = new Intent(context, DetailActivity.class);
detailActivity.putExtra(DetailActivity.EXTRA_MOUNTAIN, listMountain.get(position));
context.startActivity(detailActivity);
}
});
}
#Override
public int getItemCount() {
return getListMountain().size();
}
public class CardViewHolder extends RecyclerView.ViewHolder {
ImageView imgPhoto;
TextView tvName, tvDescription;
Button button;
public CardViewHolder(#NonNull View itemView) {
super(itemView);
imgPhoto = itemView.findViewById(R.id.img_card);
tvName = itemView.findViewById(R.id.tv_name_card);
tvDescription = itemView.findViewById(R.id.tv_desc_card);
button = itemView.findViewById(R.id.button);
}
}
#Override
public Filter getFilter(){
return new Filter() {
#Override
protected FilterResults performFiltering(CharSequence charSequence) {
String charString = charSequence.toString();
if(charString.isEmpty()){
filteredList = listMountain;
}
else
{
ArrayList<Mountain> MountainFilteredList = new ArrayList<>();
for(Mountain item : listMountain){
if(item.getName().toLowerCase().contains(charString.toLowerCase())) {
MountainFilteredList.add(item);
}
}
filteredList = MountainFilteredList;
}
FilterResults filterResults = new FilterResults();
filterResults.values = filteredList;
return filterResults;
}
#Override
protected void publishResults(CharSequence charSequence, FilterResults filterResults) {
filteredList = (ArrayList<Mountain>) filterResults.values;
notifyDataSetChanged();
}
};
}
Model:
public class Mountain implements Parcelable {
// create implementation Parcelable to this class
private String name, elevation, photo, description, location;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getElevation() {
return elevation;
}
public void setElevation(String elevation) {
this.elevation = elevation;
}
public String getPhoto() {
return photo;
}
public void setPhoto(String photo) {
this.photo = photo;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public String getLocation() {
return location;
}
public void setLocation(String location) {
this.location = location;
}
public Mountain() {
}
protected Mountain(Parcel in) {
name = in.readString();
elevation = in.readString();
photo = in.readString();
description = in.readString();
location = in.readString();
}
public static final Creator<Mountain> CREATOR = new Creator<Mountain>() {
#Override
public Mountain createFromParcel(Parcel in) {
return new Mountain(in);
}
#Override
public Mountain[] newArray(int size) {
return new Mountain[size];
}
};
#Override
public int describeContents() {
return 0;
}
#Override
public void writeToParcel(Parcel parcel, int i) {
parcel.writeString(name);
parcel.writeString(elevation);
parcel.writeString(photo);
parcel.writeString(description);
parcel.writeString(location);
}

1) In ItemCardViewAdapter() Constructor you need to pass filteredList into your listMountain list.
public ItemCardViewAdapter(MainActivity context) {
this.context = context;
listMountain= new ArrayList<>();
listMountain.addAll(filteredList);
}
2) firstly, clear listMountain and then add filteredList into listMountain list in publishResults() method.
protected void publishResults(CharSequence charSequence, FilterResults filterResults) {
listMountain.clear();
listMountain.addAll((Collection<? extends Mountain>) filterResults.values;
notifyDataSetChanged();
}

Related

Attempt to invoke virtual method 'android.os.Parcelable android.os.Bundle.getParcelable(java.lang.String)' on a null object reference

Idk why is it not working, Im trying to transfer data, i'm doing an app but when i run it i get an error, the Error is in the BlogActivity Class
"showData(getIntent().getExtras().getParcelable(EXTRAS_BLOG));"(java.lang.NullPointerException).
This is BlogActivity Class:
public class BlogActivity extends AppCompatActivity{
private static final String EXTRAS_BLOG = "EXTRAS_BLOG";
private TextView textTitle;
private TextView textDate;
private TextView textAuthor;
private TextView textRating;
private TextView textDescription;
private TextView textViews;
private RatingBar ratingBar;
private ImageView imageAvatar;
private ImageView imageMain;
private ImageView imageBack;
private ProgressBar progressBar;
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_blogpage);
imageMain = findViewById(R.id.yemenImg);
imageAvatar = findViewById(R.id.yemenAvatar);
imageBack = findViewById(R.id.imageBack);
imageBack.setOnClickListener(new View.OnClickListener()
{
#Override
public void onClick(View view)
{
new Handler().postDelayed(new Runnable()
{
#Override
public void run()
{
Intent myInt = new Intent(getApplicationContext(),MainActivity.class);
startActivity(myInt);
}
},2);
}
});
textDate = findViewById(R.id.dateYemen);
textTitle = findViewById(R.id.textTitle);
textAuthor = findViewById(R.id.yemenAuthor);
textRating = findViewById(R.id.textRating);
textViews = findViewById(R.id.textViews);
textDescription = findViewById(R.id.textDescription);
ratingBar = findViewById(R.id.ratingBar);
progressBar = findViewById(R.id.progressBar);
showData(getIntent().getExtras().getParcelable(EXTRAS_BLOG));
}
/*private void loadData()
{
BlogHttpClient.INSTANCE.loadBlogArticles(new BlogArticlesCallback() {
#Override
public void onSuccess(final List<Blog> blogList) {
runOnUiThread(new Runnable() {
#Override
public void run() {
showData(blogList.get(0));
}
});
}
#Override
public void onError() {
runOnUiThread(new Runnable() {
#Override
public void run() {
showErrorSnackbar();
}
});
}
});
}*/
private void showData(Blog blog)
{
progressBar.setVisibility(View.GONE);
textTitle.setText(blog.getTitle());
textDate.setText(blog.getDate());
textAuthor.setText(blog.getAuthor().getName());
textRating.setText(String.valueOf(blog.getRating()));
textViews.setText(String.format("(%d views)", blog.getViews()));
textDescription.setText(blog.getDescription());
textDescription.setText(Html.fromHtml(blog.getDescription(),Html.FROM_HTML_MODE_COMPACT));
ratingBar.setRating(blog.getRating());
ratingBar.setVisibility(View.VISIBLE);
imageBack.setImageResource(R.drawable.ic_baseline_arrow_back_24);
Glide.with(this)
.load(blog.getImage())
.transition(DrawableTransitionOptions.withCrossFade())
.into(imageMain);
Glide.with(this)
.load(blog.getAuthor().getAvatar())
.transform(new CircleCrop())
.transition(DrawableTransitionOptions.withCrossFade())
.into(imageAvatar);
}
/*private void showErrorSnackbar()
{
View rootView = findViewById(android.R.id.content);
Snackbar snackbar = Snackbar.make(rootView,"Error during loading blog articles",
Snackbar.LENGTH_INDEFINITE);
snackbar.setActionTextColor(Color.parseColor("#e0af1f"));
snackbar.setAction("Retry", v -> {
snackbar.dismiss();
});
snackbar.show();
}*/
public static void startBlogDetailsActivity(Activity activity, Blog blog) {
Intent intent = new Intent(activity, BlogActivity.class);
intent.putExtra(EXTRAS_BLOG, blog);
activity.startActivity(intent);
}
Blog Class:
public class Blog implements Parcelable {
private String id;
private Author author;
private String title;
private String date;
private String image;
private String description;
private int views;
private float rating;
protected Blog(Parcel in) {
id = in.readString();
title = in.readString();
date = in.readString();
image = in.readString();
description = in.readString();
views = in.readInt();
rating = in.readFloat();
author = in.readParcelable(Author.class.getClassLoader());
}
#Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(id);
dest.writeString(title);
dest.writeString(date);
dest.writeString(image);
dest.writeString(description);
dest.writeInt(views);
dest.writeFloat(rating);
dest.writeParcelable(author, 0);
}
#Override
public int describeContents() {
return 0;
}
public static final Creator<Blog> CREATOR = new Creator<Blog>() {
#Override
public Blog createFromParcel(Parcel in) {
return new Blog(in);
}
#Override
public Blog[] newArray(int size) {
return new Blog[size];
}
};
public String getTitle() {
return title;
}
public String getDate() {
return date;
}
public String getImage() {
return image;
}
public String getDescription() {
return description;
}
public int getViews() {
return views;
}
public float getRating() {
return rating;
}
public Author getAuthor() {
return author;
}
public void setAuthor(Author author) {
this.author = author;
}
public String getId() {
return id;
}
#Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Blog blog = (Blog) o;
return views == blog.views &&
Float.compare(blog.rating, rating) == 0 &&
Objects.equals(id, blog.id) &&
Objects.equals(author, blog.author) &&
Objects.equals(title, blog.title) &&
Objects.equals(date, blog.date) &&
Objects.equals(image, blog.image) &&
Objects.equals(description, blog.description);
}
#Override
public int hashCode() {
return Objects.hash(id, author, title, date, image, description, views, rating);
}
This is Main Activity Class:
public class MainActivity extends AppCompatActivity {
private MainAdapter adapter;
private SwipeRefreshLayout refreshLayout;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
adapter = new MainAdapter(blog ->
BlogActivity.startBlogDetailsActivity(this, blog));
RecyclerView recyclerView = findViewById(R.id.recylerView);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
recyclerView.setAdapter(adapter);
refreshLayout = findViewById(R.id.refresh);
refreshLayout.setOnRefreshListener(this::loadData);
loadData();
}
private void loadData()
{
refreshLayout.setRefreshing(true);
BlogHttpClient.INSTANCE.loadBlogArticles(new BlogArticlesCallback() {
#Override
public void onSuccess(final List<Blog> blogList) {
runOnUiThread(new Runnable() {
#Override
public void run() {
refreshLayout.setRefreshing(false);
adapter.submitList(blogList);
}
});
}
#Override
public void onError() {
runOnUiThread(new Runnable() {
#Override
public void run() {
refreshLayout.setRefreshing(false);
showErrorSnackbar();
}
});
}
});
}
private void showErrorSnackbar() {
View rootView = findViewById(android.R.id.content);
Snackbar snackbar = Snackbar.make(rootView,"Error during loading blog articles",
Snackbar.LENGTH_INDEFINITE);
snackbar.setActionTextColor(Color.parseColor("#e0af1f"));
snackbar.setAction("Retry", v -> {
loadData();
snackbar.dismiss();
});
snackbar.show();
}
This is MainAdapter Class:
public class MainAdapter extends ListAdapter<Blog, MainAdapter.MainViewHolder>{
public interface OnItemClickListener{
void onItemClicked(Blog blog);
}
private OnItemClickListener clickListener;
public MainAdapter(OnItemClickListener clickListener){
super(DIFF_CALLBACK);
this.clickListener = clickListener;
}
#NonNull
#Override
public MainAdapter.MainViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType)
{
LayoutInflater inflater = LayoutInflater.from(parent.getContext());
View view = inflater.inflate(R.layout.activity_listlayout,parent,false);
return new MainViewHolder(view, clickListener);
}
#Override
public void onBindViewHolder(#NonNull MainAdapter.MainViewHolder holder, int position)
{
holder.bindTo(getItem(position));
}
static class MainViewHolder extends RecyclerView.ViewHolder
{
private TextView textTitle;
private TextView textDate;
private ImageView imageAvatar;
private Blog blog;
public MainViewHolder(#NonNull View itemView, OnItemClickListener listener)
{
super(itemView);
itemView.setOnClickListener(view -> listener.onItemClicked(blog));
textTitle = itemView.findViewById(R.id.textTitle);
textDate = itemView.findViewById(R.id.textDate);
imageAvatar = itemView.findViewById(R.id.imageAvatar);
}
void bindTo(Blog blog)
{
textTitle.setText(blog.getTitle());
textDate.setText(blog.getDate());
Glide.with(itemView)
.load(blog.getAuthor().getAvatar())
.transform(new CircleCrop())
.transition(DrawableTransitionOptions.withCrossFade())
.into(imageAvatar);
}
}
private static final DiffUtil.ItemCallback<Blog> DIFF_CALLBACK =
new DiffUtil.ItemCallback<Blog>()
{
#Override
public boolean areItemsTheSame(#NonNull Blog oldItem, #NonNull Blog newItem)
{
return oldItem.getId().equals(newItem.getId());
}
#Override
public boolean areContentsTheSame(#NonNull Blog oldItem, #NonNull Blog newItem)
{
return oldItem.equals(newItem);
}
};
You may set value to blog variable in MainViewHolder.
Add this line to your bindTo() method body:
this.blog = blog

Search Filter in RecyclerView not showing anything

My app consists in letting you add lists in which you can keep your notes. Therefore, I have this
NotesListActivity where I can add and keep my Lists. I wanted to filter this lists following the https://www.youtube.com/watch?v=CTvzoVtKoJ8 tutorial and then I tried to adapt it to my code like below. Could you please tell me what is the problem here, cause I don't even get an error, I just not get any title of list as result.
So, this is what I have in my RecyclerAdapter:
public class NotesRecyclerAdapter extends RecyclerView.Adapter<NotesRecyclerAdapter.ViewHolder> implements Filterable {
private static final String TAG = "NotesRecyclerAdapter";
ArrayList<Note> notesListAll;
private ArrayList<Note> mNotes;
private OnNoteListener mOnNoteListener;
public NotesRecyclerAdapter(ArrayList<Note> mNotes, OnNoteListener onNoteListener) {
this.mNotes = mNotes;
this.mOnNoteListener = onNoteListener;
this.notesListAll = new ArrayList<>();
notesListAll.addAll(mNotes);
}
#NonNull
#Override
public ViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
...
}
#Override
public void onBindViewHolder(#NonNull ViewHolder holder, int position) {
...
}
#Override
public int getItemCount() {
return mNotes.size();
}
#Override
public Filter getFilter() { return myFilter; }
Filter myFilter = new Filter() {
//runs on background thread
#Override
protected FilterResults performFiltering(CharSequence charSequence) {
List<Note> filteredList = new ArrayList<>();
if (charSequence == null || charSequence.length() == 0) {
filteredList.addAll(notesListAll);
} else {
for (Note note : notesListAll) {
if (note.getTitle().toLowerCase().contains(charSequence.toString().toLowerCase())) {
filteredList.add(note);
}
}
}
FilterResults filterResults = new FilterResults();
filterResults.values = filteredList;
return filterResults;
}
//runs on a ui thread
#Override
protected void publishResults(CharSequence charSequence, FilterResults filterResults) {
mNotes.clear();
mNotes.addAll((Collection <? extends Note>) filterResults.values );
notifyDataSetChanged();
}
};
public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
...
}
#Override
public void onClick(View view) {
...
}
}
public interface OnNoteListener{
void onNoteClick(int position);
}
}
And this in my Activity:
public class NotesListActivity extends AppCompatActivity implements
NotesRecyclerAdapter.OnNoteListener,
FloatingActionButton.OnClickListener
{
private static final String TAG = "NotesListActivity";
private RecyclerView mRecyclerView;
private ArrayList<Note> mNotes = new ArrayList<>();
private NotesRecyclerAdapter mNoteRecyclerAdapter;
private NoteRepository mNoteRepository;
#Override
protected void onCreate(Bundle savedInstanceState) {
...
initRecyclerView();
mNoteRepository = new NoteRepository(this);
retrieveNotes();
setSupportActionBar((Toolbar)findViewById(R.id.notes_toolbar));
setTitle("Notes");
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.search,menu);
MenuItem item = menu.findItem(R.id.action_search);
SearchView searchView = (SearchView) item.getActionView();
searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
#Override
public boolean onQueryTextSubmit(String query) {
return false;
}
#Override
public boolean onQueryTextChange(String newText) {
// NotesRecyclerAdapter.getFilter().filter(newText);
mNoteRecyclerAdapter.getFilter().filter(newText);
return false;
}
});
return super.onCreateOptionsMenu(menu);
}
private void retrieveNotes() {
mNoteRepository.retrieveNotesTask().observe(this, new Observer<List<Note>>() {
#Override
public void onChanged(#Nullable List<Note> notes) {
...
}
});
}
private void initRecyclerView(){
...
}
#Override
public void onNoteClick(int position) {
...
}
#Override
public void onClick(View view) {
...
}
private void deleteNote(Note note) {
...
}
ItemTouchHelper.SimpleCallback itemTouchHelperCallback = new ItemTouchHelper.SimpleCallback(0, ItemTouchHelper.RIGHT) {
#Override
public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder target) {
return false;
}
#Override
public void onSwiped(RecyclerView.ViewHolder viewHolder, int direction) {
deleteNote(mNotes.get(viewHolder.getAdapterPosition()));
}
};
}
You need to check if it's the first intance or not.
if (firstInstance) {notesList.clear();}
notesList.addAll(notesListAll);
The problem is that you are using an empty notesListAll list for filtering results; you need to populate it with the list of notes in the constructor
public NotesRecyclerAdapter(ArrayList<Note> mNotes, OnNoteListener onNoteListener) {
this.mNotes = mNotes;
this.mOnNoteListener = onNoteListener;
this.notesListAll = new ArrayList<>(); // <---- Empty list
notesListAll.addAll(mNotes); // <--- Fix is here
}
Also, you're filtering based on getContent(), probably the searched text is not a part of that content, so you need to filter out some other results within the Note data class.
if (note.getContent().toLowerCase().contains(charSequence.toString().toLowerCase())) {
I just solved it out this way
notesListAll.addAll(mNotes);
to
notesListAll = mNotes;

How does positioning work in RecyclerView?

So I have a little problem where I have a giant recycler view (7000 items) and I have it filled up with generated cards that have college information on them and a button on the right hand side. I included a picture for you to see exactly what I mean. So here is the question: I want to fetch the name and ID when I click on the "details" button so that I can query the rest of college information from an SQLite database later but when I scroll down enough and click the button it sometimes returns information of other college instead of the one I want. The first one always works as intended though. Here is the adapter code:
public class CustomRecyclerAdapter extends RecyclerView.Adapter<CustomRecyclerAdapter.CustomViewHolder> implements Filterable {
private List<CollegeItem> collegeList;
private List<CollegeItem> collegeListFull;
private ItemClickListener itemClickListener;
private Context context;
private Button details;
private DatabaseCollege collegeDB;
public CustomRecyclerAdapter(List<CollegeItem> collegeList, Context context) {
this.collegeList = collegeList;
this.context = context;
collegeListFull = new ArrayList<>(collegeList);
}
#NonNull
#Override
public CustomRecyclerAdapter.CustomViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View itemView = LayoutInflater.from(context).inflate(R.layout.college_item, parent, false);
return new CustomRecyclerAdapter.CustomViewHolder(itemView);
}
#Override
public void onBindViewHolder(CustomRecyclerAdapter.CustomViewHolder holder, int position) {
final String id = collegeList.get(position).getId();
final String name = collegeList.get(position).getName();
holder.name.setText(collegeList.get(position).getName());
holder.id.setText(collegeList.get(position).getId());
details.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
System.out.println(id + " - " + name); //This sometimes gives information of incorrect college when clicked
}
});
}
#Override
public int getItemCount() {
return collegeList.size();
}
public void setItemClickListener(ItemClickListener itemClickListener) {
this.itemClickListener = itemClickListener;
}
#Override
public Filter getFilter() {
return collegeFilter;
}
public Filter getFilterName() {
return collegeFilterName;
}
private Filter collegeFilter = new Filter() {
#Override
protected FilterResults performFiltering(CharSequence constraint) {
List<CollegeItem> filteredList = new ArrayList<>();
if(constraint == null || constraint.length() == 0) {
filteredList.addAll(collegeListFull);
} else {
String filterPattern = constraint.toString().toLowerCase().trim();
for(CollegeItem college : collegeListFull) {
if(college.getName().toLowerCase().contains(filterPattern)) {
filteredList.add(college);
}
}
}
FilterResults results = new FilterResults();
results.values = filteredList;
return results;
}
#Override
protected void publishResults(CharSequence constraint, FilterResults results) {
collegeList.clear();
collegeList.addAll((List) results.values);
notifyDataSetChanged();
}
};
private Filter collegeFilterName = new Filter() {
#Override
protected FilterResults performFiltering(CharSequence constraint) {
List<CollegeItem> filteredList = new ArrayList<>();
if(constraint == null || constraint.length() == 0) {
filteredList.addAll(collegeListFull);
} else {
String filterPattern = constraint.toString().toLowerCase().trim();
for(CollegeItem college : collegeListFull) {
if(college.getId().toLowerCase().contains(filterPattern)) {
filteredList.add(college);
}
}
}
FilterResults results = new FilterResults();
results.values = filteredList;
return results;
}
#Override
protected void publishResults(CharSequence constraint, FilterResults results) {
collegeList.clear();
collegeList.addAll((List) results.values);
notifyDataSetChanged();
}
};
public class CustomViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
TextView name, id;
public CustomViewHolder(View v) {
super(v);
name = v.findViewById(R.id.college_name);
id = v.findViewById(R.id.college_id);
details = v.findViewById(R.id.btn_college_details);
}
#Override
public void onClick(View v) {
if(itemClickListener != null) {
itemClickListener.onClick(v, getAdapterPosition());
}
}
}
}
I am not sure exactly why but it seems to be a positioning issue maybe? Because when I scroll and click the information outputed seem to change. Whats the correct way to get the information from the cards the way I want?
and just in case here is the fragment java code where the recycler view sits:
public class CollegeFragment extends Fragment implements ItemClickListener{
private RecyclerView recyclerView;
private CustomRecyclerAdapter customRecyclerAdapter;
private List<CollegeItem> collegeItemList = new ArrayList<>();
private DatabaseCollege dbCollege;
private EditText cName, cId;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
final View myFragmentView = inflater.inflate(R.layout.fragment_college, container, false);
dbCollege = new DatabaseCollege(getActivity());
recyclerView = myFragmentView.findViewById(R.id.recycler);
customRecyclerAdapter = new CustomRecyclerAdapter(dbCollege.getCollegeData(), getActivity());
RecyclerView.LayoutManager layoutManager = new LinearLayoutManager(getActivity(), LinearLayoutManager.VERTICAL, false);
recyclerView.setLayoutManager(layoutManager);
recyclerView.setItemAnimator(new DefaultItemAnimator());
recyclerView.setAdapter(customRecyclerAdapter);
customRecyclerAdapter.setItemClickListener(this);
cId = myFragmentView.findViewById(R.id.et_ipeds);
cId.addTextChangedListener(new TextWatcher() {
#Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
#Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
cName.getText().clear();
CollegeFragment.this.customRecyclerAdapter.getFilter().filter(s);
}
#Override
public void afterTextChanged(Editable s) {
}
});
cName = myFragmentView.findViewById(R.id.et_name);
cName.addTextChangedListener(new TextWatcher() {
#Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
#Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
cId.getText().clear();
CollegeFragment.this.customRecyclerAdapter.getFilterName().filter(s);
}
#Override
public void afterTextChanged(Editable s) {
}
});
return myFragmentView;
}
#Override
public void onClick(View v, int position) {
String name = collegeItemList.get(position).getName();
String id = collegeItemList.get(position).getId();
}
}
Adapter
public class CustomRecyclerAdapter extends RecyclerView.Adapter<CustomRecyclerAdapter.CustomViewHolder> implements Filterable {
private List<CollegeItem> collegeList;
private List<CollegeItem> collegeListFull;
private ItemClickListener itemClickListener;
private Context context;
private DatabaseCollege collegeDB;
public CustomRecyclerAdapter(List<CollegeItem> collegeList, Context context) {
this.collegeList = collegeList;
this.context = context;
collegeListFull = new ArrayList<>(collegeList);
}
#NonNull
#Override
public CustomRecyclerAdapter.CustomViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View itemView = LayoutInflater.from(context).inflate(R.layout.college_item, parent, false);
return new CustomRecyclerAdapter.CustomViewHolder(itemView);
}
#Override
public void onBindViewHolder(CustomRecyclerAdapter.CustomViewHolder holder, int position) {
final String id = collegeList.get(position).getId();
final String name = collegeList.get(position).getName();
holder.name.setText(collegeList.get(position).getName());
holder.id.setText(collegeList.get(position).getId());
}
#Override
public int getItemCount() {
return collegeList.size();
}
public void setItemClickListener(ItemClickListener itemClickListener) {
this.itemClickListener = itemClickListener;
}
#Override
public Filter getFilter() {
return collegeFilter;
}
public Filter getFilterName() {
return collegeFilterName;
}
private Filter collegeFilter = new Filter() {
#Override
protected FilterResults performFiltering(CharSequence constraint) {
List<CollegeItem> filteredList = new ArrayList<>();
if(constraint == null || constraint.length() == 0) {
filteredList.addAll(collegeListFull);
} else {
String filterPattern = constraint.toString().toLowerCase().trim();
for(CollegeItem college : collegeListFull) {
if(college.getName().toLowerCase().contains(filterPattern)) {
filteredList.add(college);
}
}
}
FilterResults results = new FilterResults();
results.values = filteredList;
return results;
}
#Override
protected void publishResults(CharSequence constraint, FilterResults results) {
collegeList.clear();
collegeList.addAll((List) results.values);
notifyDataSetChanged();
}
};
private Filter collegeFilterName = new Filter() {
#Override
protected FilterResults performFiltering(CharSequence constraint) {
List<CollegeItem> filteredList = new ArrayList<>();
if(constraint == null || constraint.length() == 0) {
filteredList.addAll(collegeListFull);
} else {
String filterPattern = constraint.toString().toLowerCase().trim();
for(CollegeItem college : collegeListFull) {
if(college.getId().toLowerCase().contains(filterPattern)) {
filteredList.add(college);
}
}
}
FilterResults results = new FilterResults();
results.values = filteredList;
return results;
}
#Override
protected void publishResults(CharSequence constraint, FilterResults results) {
collegeList.clear();
collegeList.addAll((List) results.values);
notifyDataSetChanged();
}
};
public class CustomViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
TextView name, id;
Button details; // Button should be here
public CustomViewHolder(View v) {
super(v);
name = v.findViewById(R.id.college_name);
id = v.findViewById(R.id.college_id);
details = v.findViewById(R.id.btn_college_details);
details.setOnClickListener(this); // set click listener here instead
}
#Override
public void onClick(View v) {
if(itemClickListener != null) {
itemClickListener.onClick(v, getAdapterPosition());
}
}
}
}
Here, you're utilizing the ItemClickListener callback that you implemented in your fragment instead of creating new instances of click listener for your details button. In this case, your listener for all items is your Fragment that implements ItemClickListener

Data from Firebase did not show in RecyclerView

My RecyclerView not show any data from Firebase. I don't see any errors at logcat so I don't know why. I followed guide from youtube video. But still nothing. I'm using android 8.0 and API 27. Hope Somebody can help.
My Main Activity Code:
public class ViewProduct extends AppCompatActivity {
DatabaseReference ref;
ArrayList<Model> list;
private RecyclerView recyclerView;
private RecyclerView.Adapter viewHolder;
private RecyclerView.LayoutManager layoutManager;
SearchView searchView;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_view_product) ;
ref = FirebaseDatabase.getInstance().getReference().child("buddymealplanneruser").
child("Products");
recyclerView = findViewById(R.id.stallproductRecyclerView);
//recyclerView.setHasFixedSize(true);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
//SEARCH VIEW
searchView = findViewById(R.id.searchProductStall);
//ADAPTER
list = new ArrayList<>();
viewHolder = new ViewHolder(list);
recyclerView.setAdapter(viewHolder);
}
#Override
protected void onRestart() {
super.onRestart();
if (ref!=null)
{
ref.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
if (dataSnapshot.exists())
{
//list = new ArrayList<>();
list.clear();
for(DataSnapshot ds : dataSnapshot.getChildren())
{
list.add(ds.getValue(Model.class));
}
//ViewHolder viewHolder = new ViewHolder(list);
//recyclerView.setAdapter(viewHolder);
viewHolder.notifyDataSetChanged();
}
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
Toast.makeText(ViewProduct.this, databaseError.getMessage(),
Toast.LENGTH_SHORT).show();
}
});
}
if (searchView !=null)
{
searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
#Override
public boolean onQueryTextSubmit(String s)
{
return false;
}
#Override
public boolean onQueryTextChange(String s) {
search(s);
return true;
}
});
}
}
private void search(String str) {
ArrayList<Model> myList = new ArrayList<>();
for(Model object : list)
{
if(object.getProductName().toLowerCase().contains(str.toLowerCase()))
{
myList.add(object);
}
}
ViewHolder viewHolder = new ViewHolder(myList);
recyclerView.setAdapter(viewHolder);
}
}
My Adapter:
public class ViewHolder extends RecyclerView.Adapter<ViewHolder.MyViewHolder> {
ArrayList<Model> list;
public ViewHolder (ArrayList<Model> list)
{
this.list=list;
}
#NonNull
#Override
public MyViewHolder onCreateViewHolder(#NonNull ViewGroup viewGroup, int i) {
View view = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.row_product, viewGroup,false);
return new MyViewHolder(view);
}
#Override
public void onBindViewHolder(#NonNull MyViewHolder myViewHolder, int i) {
myViewHolder.productName.setText(list.get(i).getProductName());
myViewHolder.productCalorie.setText(list.get(i).getProductCalorie());
myViewHolder.StallId.setText(list.get(i).getStallId());
myViewHolder.productType.setText(list.get(i).getProductType());
myViewHolder.productServing.setText(list.get(i).getProductServing());
myViewHolder.statusProduct.setText(list.get(i).getStatusProduct());
}
#Override
public int getItemCount()
{
return list.size();
}
class MyViewHolder extends RecyclerView.ViewHolder
{
TextView productName, productCalorie, StallId;
TextView productType, productServing, statusProduct;
ImageView productImageView;
public MyViewHolder (#NonNull View itemView){
super((itemView));
productName = itemView.findViewById(R.id.productTitle);
productCalorie = itemView.findViewById(R.id.productDescriptionCalorie);
StallId = itemView.findViewById(R.id.productDescriptionStallId);
productType = itemView.findViewById(R.id.productDescriptionType);
productServing=itemView.findViewById(R.id.productDescriptionServing);
statusProduct=itemView.findViewById(R.id.productDescriptionAvailibility);
//productImageView = itemView.findViewById(R.id.productImageView);
}
}
}
My Model :
package com.example.buddymealplannerstall.Child;
import android.view.Display;
public class Model {
//String productName, productImage, productCalorie, StallId, productType, productServing, statusProduct;
private String StallId;
private String productCalorie;
private String productImage;
private String productName;
private String productServing;
private String productType;
private String statusProduct;
public Model (String StallId,
String productCalorie,
String productImage,
String productName,
String productServing,
String productType,
String statusProduct){
this.StallId = StallId;
this.productCalorie = productCalorie;
this.productImage = productImage;
this.productName = productName;
this.productServing = productServing;
this.productType = productType;
this.statusProduct = statusProduct;
}
public Model(){
}
public String getStallId() {
return StallId;
}
public void setStallId(String stallId) {
StallId = stallId;
}
public String getProductCalorie() {
return productCalorie;
}
public void setProductCalorie(String productCalorie) {
this.productCalorie = productCalorie;
}
public String getProductImage() {
return productImage;
}
public void setProductImage(String productImage) {
this.productImage = productImage;
}
public String getProductName() {
return productName;
}
public void setProductName(String productName) {
this.productName = productName;
}
public String getProductServing() {
return productServing;
}
public void setProductServing(String productServing) {
this.productServing = productServing;
}
public String getProductType() {
return productType;
}
public void setProductType(String productType) {
this.productType = productType;
}
public String getStatusProduct() {
return statusProduct;
}
public void setStatusProduct(String statusProduct) {
this.statusProduct = statusProduct;
}
}
Screen Shot of my firebase and my apps.
firebase
my app
According to your comment:
yes, buddymealplanner is my project's name
Please note that there is no need to add the name of your project as a child in the reference. So please change the following line of code:
ref = FirebaseDatabase.getInstance().getReference().child("buddymealplanneruser").
child("Products");
Simply to:
ref = FirebaseDatabase.getInstance().getReference().child("Products");
I dont think you are populating your list, you are sending it empty. From what I can see, you only add items to the list when you are restarting the activity. Try either populating it before sendinig the list, or changing the onRestart() for an onStart() or an onResume().

Unchecked assignment warning after creating adapter for RecyclerView

After creating an adapter for my RecyclerView, I noticed a warning. How can this warning be resolved?
(List) results.values in myList.addAll((List) results.values); returns a warning:
Unchecked assignment: 'java.util.List' to 'java.util.Collection <? extends com.companyname.appname.Product>'
'Product' class
public class Product {
public Product(){}
private String mProductName;
private String mProductDescription;
public Product(String productName, String productDescription) {
this.mProductName = productName;
this.mProductDescription = productDescription;
}
public String getProductName() {
return mProductName;
}
public void setProductName(String item){
this.mProductName = item;
}
public String getProductDescription() {
return mProductDescription;
}
public void setProductDescription(String description){
this.mProductDescription = description;
}
}
Activity class
public class MyActivity extends AppCompatActivity {
private static final String TAG = MyActivity.class.getSimpleName();
private Boolean mCurrentValue;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.md);
}
#Override
protected void onStart() {
super.onStart();
setContentView(R.layout.md);
}
}
Fragment class
public class MyFragment extends Fragment {
public MyFragment() {}
private MyListAdapter mAdapter;
RecyclerView mRecyclerView;
public boolean mTwoPane;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setHasOptionsMenu(true);
}
#Override
public View onCreateView(#NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.activity_main, container, false);
mTwoPane = Objects.requireNonNull(getActivity()).findViewById(R.id.detail_container) != null;
mRecyclerView = view.findViewById(R.id.recyclerView_list);
mRecyclerView.setHasFixedSize(true);
mRecyclerView.setLayoutManager(new LinearLayoutManager(this.getActivity()));
mRecyclerView.addItemDecoration(new DividerItemDecoration(Objects.requireNonNull(getContext()), LinearLayout.VERTICAL));
ArrayList<Product> myList = new ArrayList<>();
String[] items = getResources().getStringArray(R.array.product_names);
String[] itemDescriptions = getResources().getStringArray(R.array.product_descriptions);
for (int n = 0; n < items.length; n++){
Product product = new Product();
product.setProductName(items[n]);
product.setFareZone(itemDescriptions[n]);
myList.add(product);
}
mAdapter = new MyListAdapter(getActivity(), myList, mTwoPane);
mRecyclerView.setAdapter(mAdapter);
return view;
}
}
Adapter class
public class MyListAdapter extends RecyclerView.Adapter<MyListAdapter.ProductViewHolder> implements Filterable {
private Context mCtx;
private List<Product> myList;
private List<Product> myListFull;
private boolean mTwoPane;
class ProductViewHolder extends RecyclerView.ViewHolder {
RelativeLayout relativeLayout;
TextView textviewTitle, textviewSubtitle;
ProductViewHolder(View itemView) {
super(itemView);
relativeLayout = itemView.findViewById(R.id.listitem_dualline_relativelayout);
textviewTitle = itemView.findViewById(R.id.listitem_dualline_title);
textviewSubtitle = itemView.findViewById(R.id.listitem_dualline_subtitle);
}
}
public MyListAdapter(Context mCtx, List<Product> myList, boolean mTwoPane) {
this.mCtx = mCtx;
this.myList = myList;
this.mTwoPane = mTwoPane;
myListFull = new ArrayList<>(myList);
}
#NonNull
#Override
public MyListAdapter.ProductViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
LayoutInflater inflater = LayoutInflater.from(mCtx);
View v = inflater.inflate(R.layout.listitem_dualline, parent,false);
return new MyListAdapter.ProductViewHolder(v);
}
#Override
public void onBindViewHolder(#NonNull final MyListAdapter.ProductViewHolder holder, final int position) {
Log.d(TAG, "onBindViewHolder: called.");
final Product product = myList.get(holder.getAdapterPosition());
holder.textviewTitle.setText(product.getProductName());
holder.textviewSubtitle.setText(product.getProductDescription());
}
#Override
public int getItemCount() {
return myList.size();
}
#Override
public Filter getFilter() {
return exampleFilter;
}
private Filter exampleFilter = new Filter() {
#Override
protected FilterResults performFiltering(CharSequence constraint) {
List<Product> filteredList = new ArrayList<>();
if (constraint == null || constraint.length() == 0) {
filteredList.addAll(myListFull);
} else {
String filterPattern = constraint.toString().toLowerCase().trim();
for (Product item : myListFull) {
if (item.getProductName().toLowerCase().contains(filterPattern)) {
filteredList.add(item);
}
}
}
FilterResults results = new FilterResults();
results.values = filteredList;
return results;
}
#Override
protected void publishResults(CharSequence constraint, FilterResults results) {
myList.clear();
myList.addAll((List) results.values);
notifyDataSetChanged();
}
};
}
Replace:
myList.addAll((List) results.values);
with:
myList.addAll((List<Product>) results.values);
Try this:
myList.addAll((Collection<? extends Products>) results.values);

Categories

Resources