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

83,284

Solution 1

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

Solution 2

In some cases changing only visibility attribute might still end up as allocated blank space (because of parent view's padding, margins, inner elements etc). Then changing height of the parent view helps:

holder.itemView.setVisibility(View.GONE); 
holder.itemView.setLayoutParams(new RecyclerView.LayoutParams(0, 0));

Then be sure that in the condition that it should be visible, also set:

holder.itemView.setVisibility(View.VISIBLE);
holder.itemView.setLayoutParams(new RecyclerView.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT));

You need to do that because the viewHolder is recycled as you scroll, if you change properties as this and never return them to their natural state, other elements will be already hidden in the event they reuse the same view.

Solution 3

IF

view.setVisibility(View.GONE);

gives you a Blank view

Then follow This.

public static class Data_ViewHolder extends RecyclerView.ViewHolder {
    private final LinearLayout layout;
    final LinearLayout.LayoutParams params;

    public Show_Chat_ViewHolder(final View itemView) {
        super(itemView);
        .
        .
        .
        layout =(LinearLayout)itemView.findViewById(R.id.show_item_layout);
        params = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, 
        ViewGroup.LayoutParams.WRAP_CONTENT);
        .
        .
        .
    }

    private void Layout_hide() {
        params.height = 0;
        //itemView.setLayoutParams(params); //This One.
        layout.setLayoutParams(params);   //Or This one.

    }
  }

Now Call from Adapter

mFirebaseAdapter = new FirebaseRecyclerAdapte......{
public void populateViewHolder.....{

if(model.getData().equals("..Something.."))
  {
      viewHolder.Layout_hide();
  }
else
      viewHolder.Person_Email(model.getEmail());
   }
 }

Solution 4

If you are hiding whole itemView and facing the problem of blank spaces.

Try this to hide the itemView.

holder.itemView.setVisibility(View.GONE);
ViewGroup.LayoutParams params = holder.itemView.getLayoutParams();
params.height = 0;
params.width = 0;
holder.itemView.setLayoutParams(params);

And this to show it.

holder.itemView.setVisibility(View.VISIBLE);

This is a recyclerView, so use both in if else block or you might encounter some unintended UI issues.

Solution 5

"GONE" will not remove the space occupied by the item ....you can use

if (condition) {
         item.layoutParams.height = 0
         item.layoutParams.width = 0
}

inside "onBindViewHolder"

Share:
83,284
Dhaval
Author by

Dhaval

I believe that writing a piece of code is a way to express creativity. I am under the impression that simplicity is the ultimate sophistication. Hence, I focus on developing an app which is simple in terms of User Experience and rich in terms of Functionality and User Interface.

Updated on July 05, 2022

Comments

  • Dhaval
    Dhaval almost 2 years

    I am using Firebase Recycler Adapter (Firebase UI Library) to populate Recycler View. I want to hide an item(row) on a condition. I have a LinearLayout containing a recycler view.

    I set linear layout visibility to Gone in populateViewHolder() method of recycler view adapter.

    @Override
    protected void populateViewHolder(UsersViewHolder viewHolder, User user, int position) {
    
        if (user.getUserEmail().equals(Utils.decodeEmail(userEmail))) {
            viewHolder.llMain.setVisibility(View.GONE);
            return;
        }
    
        viewHolder.tvUserEmail.setText(user.getUserEmail());
    }
    

    It hides the LinearLayout but the row remains there with empty space.

    Is there any method I should override to overcome this or is there any way to achieve the result?

  • Dhaval
    Dhaval over 7 years
    But I haven't implemented custom RecyclerView Adapter. As I mentioned, I am using FirebaseRecyclerAdapter.
  • Dhaval
    Dhaval over 7 years
    This looks promising. I will definitely try this.
  • Cătălin Florescu
    Cătălin Florescu over 7 years
    You can add a method in ViewHolder, like show() / hide() that handle all that work of visibility. Don't forget that is a recycler view, so you need to show view holder if condition is not met, otherwise will hide unwanted items.
  • Dhaval
    Dhaval over 7 years
    Sorry to say, But, once the size of items increased, the problem occurs again and the blank spaces again appears. What should I do to solve the issue?
  • Cătălin Florescu
    Cătălin Florescu over 7 years
    Hide all items, including parents, cards. I had the same problem, but i resolved hinding all items.
  • Dhaval
    Dhaval over 7 years
    I did as you suggested. But still problem seems to be exist. Here is my code. pastebin.com/8f4PAsh3
  • Cătălin Florescu
    Cătălin Florescu over 7 years
    When i said all element, i reffer to your LinearLayout, Relative, TextView and ImageView, not itemview.
  • Dhaval
    Dhaval over 7 years
    Sorry, I misunderstood. Your solution works fine. Thank you.
  • MeLean
    MeLean almost 7 years
    This is better solution than view.setVisibility(View.GONE);. Because you don't have to clear margins and decorations of the ViewHolder.
  • Cătălin Florescu
    Cătălin Florescu over 6 years
    All depending of your entire view. If you have a LinearLayout and use GONE, you view will retract fine.
  • chornge
    chornge about 6 years
    i used itemView.setLayoutParams(...) and it worked beautifully for me. thanks!
  • anonymous
    anonymous about 6 years
    Although it's working great for linear recyclerview but not removing vacant space in grid recyclerview
  • Justin Ebby
    Justin Ebby almost 6 years
    This worked, but I am using a grid recyclerview, and there is a blank cell or two in between.
  • Ali.DM
    Ali.DM over 5 years
    Don't forget to return Visibility of the view back to VISIBLE & LayoutParams to it's initial state in opposite case.In my case: holder.lin.setLayoutParams(new RecyclerView.LayoutParams(ViewGroup.LayoutParams.MATCH_PAREN‌​T, ViewGroup.LayoutParams.WRAP_CONTENT));
  • Nouman Ch
    Nouman Ch about 5 years
    this is perfect.
  • htafoya
    htafoya almost 5 years
    Nice, however your java conventions seems odd by using snake_case and capital case methods
  • htafoya
    htafoya almost 5 years
    This works only if your itemView is a data in an array, because it may be a header or other kind of element that you want to delete that will mess all around if you do this.
  • MisseMask
    MisseMask over 4 years
    If you get a crash by doing this! Make sure you you try "params = itemView.getLayoutParams()" then set the width/height on that params object. After that: "itemView.setLayoutParams(params)".
  • Amr Jyniat
    Amr Jyniat over 4 years
    That's so perfect! but pay attention, the design for your RecyclerView will hide too when set the holder is visible. to resolve this just delete line 2 in the last code.
  • Yaswant Narayan
    Yaswant Narayan almost 4 years
    Sometimes even after doing this I still got white spaces. So, for that I did recyclerView.requestLayout() after changing layoutparams and it worked fine.
  • Alaa M.
    Alaa M. almost 4 years
    @FlorescuCătălin - Sorry for bringing up the conversation again after 4 years... But how do you get the LinearLayout from the view holder?
  • MeLean
    MeLean over 3 years
    you should set the height and width back in else statement!
  • Fabian
    Fabian about 3 years
    Please try to improve the other answers or provide a real answer instead of writing a answer that only is a comment to them.
  • incognito
    incognito almost 3 years
    @KoustuvGanguly you are welcome. I'm surprised to see that after 4 years this issue is still relevant :)