How to Hide an Item from Recycler View on a Particular Condition

How to hide an item from Recycler View on a particular condition?

You should hide all views or parent from UsersViewholder layout xml.
You should hide entire viewholder or each view

Entire viewholder:

itemView.setVisibility(View.GONE);

or each element:

view.setVisibility(View.GONE);

But don't forget to set them VISIBLE otherwise, you will end up with some strange things from recycling

How to hide a child item in a recyclerView based on a condition?

You're changing the visibility of the views but not defining the else condition properly. Sometimes the recyclerview doesn't refresh views properly because of that ambiguity.

Try this:

    if(model.main_category == "Food") {
holder.itemView.tv_dashboard_item_type.visibility = View.VISIBLE
holder.itemView.tv_dashboard_item_type.text = "Perishable"
} else {
holder.itemView.tv_dashboard_item_type.visibility = View.GONE
}

Hope that works!

How to hide/display specific RecyclerView item?


although the entry is hidden, the space it occupied was still there

  • may be because you are hiding the child but its parent is still there with its height or padding given

How can I toggle the visibility of this specific entry to VISIBLE/GONE in my RecyclerView

  • Toggle the visibility of parent

In your onBindViewHolder

 @Override
public void onBindViewHolder(@NonNull MyViewHolder viewHolder, int i) {

if (isButtonPressed) {
viewHolder.parentViewId.setVisibility(View.GONE);
}else {
viewHolder.parentViewId.setVisibility(View.VISIBLE);
}
}

Create a public boolean isButtonPressed; and when you press the button make it true and call adapter.notifyDataSetChanged();

How can I hide an ImageView on my RecyclerView for certain items based on a particular condition?

Add a boolean flag to your ReportItem class for each RecyclerView item. You will need to specify which rows show or hide this field when each item is created:

public class ReportItem {

private String departureDate;
private String flightNumber;
private Boolean showMailIcon;

public ReportItem(String departureDate, String flightNumber, Boolean showMailIcon) {
this.departureDate = departureDate;
this.flightNumber = flightNumber;
this.showMailIcon = showMailIcon
}

public String getDepartureDate() {
return departureDate;
}

public String getFlightNumber() {
return flightNumber;
}

public String getShowMailIcon() {
return showMailIcon;
}
}

Then update the onBindViewHolder() method override to use this flag to show/hide the ImageView:

@Override
public void onBindViewHolder(@NonNull ReportViewHolder holder, int position) {

ReportItem currentItem = reportlist.get(position);

if (currentItem.getShowMailIcon() == true) {
holder.mailIcon.setVisibility(View.VISIBLE);
} else {
holder.mailIcon.setVisibility(View.GONE);
}


//.......
}

Hide recyclerview when there is no item to show with condition


i have used adapter.registerAdapterDataObserver(); method but it doesn't works .

I don't know how you used registerAdapterDataObserver() but here is the correct approch of using it. So to know the number of items that are returned by the query, you need to use getItemCount() method that exist in your adapter class. Because the data from Firebase realtime database is loaded asynchronously, you cannot simply call getItemCount() directly in your adapter class, as it will always be zero. So in order to get the total number of items, you need to register an observer like in the following lines of code:

adapter.registerAdapterDataObserver(new RecyclerView.AdapterDataObserver() {
public void onItemRangeInserted(int positionStart, int itemCount) {
int totalNumberOfItems = adapter.getItemCount();
Log.d(TAG, String.valueOf(totalNumberOfItems));
if(totalNumberOfItems == 0) {
recyclerView.setVisibility(View.GONE);
emptyInfoTextView.setVisibility(View.VISIBLE);
}
}
});

How to provide conditional visibility of a child-item in a RecyclerView in the Adapter class?

A RecyclerView.Adapter what it does is to: recycle items (as the name implies). The list doesn't have one view per item on the data source at the same time. The adapter makes sure to have enough views in memory in order to always render the list smoothly. When a row is leaving the field of view by scrolling, then that view is recycled to be re-used in the next entering view to the screen size.

This means that onCreateViewHolder is called only when a view is needed to be created. Generally at the start of the adapter, also when the user is scrolling fast or erratically and when the data set changes and is needed.

The other method onBindViewHolder is called every time the data on the row needs to be updated in order for the view to get updated. This is called every time a row is entering the view field of the screen.

So the textbook answer is: do it on onBindViewHodlder, because if the attribute isAdmin changes then that row will need to be updated. By doing it on onCreateViewHolder that would only happen one time when the row is created.

But, your isAdmin is a val on the constructor that can not be reassigned, so this means that when the rows are created the button will be hidden or visible forever. And this doesn't matter because your structure is to determine if is admin from another source that is separated from which the row data structure is derived from.

If in some case you want to:

  • make it more flexible and easier to maintain in the future
  • or maybe you know there is going to be a case where there is gonna be a list with admins and not admins rows

Then the solution is to move the isAdming attribute to your NoticeModel, that would imply changing your data structure.

If you want to verify anything sai above, get a data source with plenty of items and then add 2 logs, one on onCreateViewHolder and one in onBindViewHolder. You will see how on create is called only sometimes but on bind is called always.

Hiding views in RecyclerView

There is no built in way to hide a child in RV but of course if its height becomes 0, it won't be visible :). I assume your root layout does have some min height (or exact height) that makes it still take space even though it is GONE.

Also, if you want to remove a view, remove it from the adapter, don't hide it. Is there a reason why you want to hide instead of remove ?

Skip items in recycler view

Lets go in depth as of how recycler view works

we have 2 functions onCreateView and onBindview. As the names of functions are quite self explaining onCreateView creates the view and onBindView takes the created view and binds data into it

now lets assume that entire view type is similar and you use an array of objects or cursor to populate the entire view.

so in bindView in order to fetch data you must have used either

 cursor.moveToPosition(position)

or

 mList.get(position)

as you can see that binding is happening based on the position that we get from onBindView arguments

@Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, final int position) {
//mList.get(position) or cursor.moveToPosition
}

so you can use this knowledge to specifically skip binding of view

say you have a function which accepts postion as parameter and returns actual position as result

private int getActualPostion(int position){
//your logic to skip the given postion
//say if(position == 4){return postion+2}
}

so you can implement something like this

@Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, final int position) {
mList.get(getActualPosition(position));
}

this will allow you to skip those view which are not to be shown

finally in method getCount which is used by recycler view to decide the number of views

 @Override
public int getItemCount() {
//foreach in array { if(already downloaded) i++}
// return array.size - i
}

I hope this helps
this will also give your more flexibility in a way that u may add more filters and use same dataset ... skip views more easily



Related Topics



Leave a reply



Submit