17

I need to add a small strip in between items of a RecyclerView. This strip can come after different number of items in a list. This needs to be done dynamically. I need to implement something like what FitBit has done:enter image description here

I also need the first row i.e. the one saying "This Week" to stick on top even if the page scrolls down.

Sid
  • 1,270
  • 2
  • 15
  • 30
  • 3
    You have to use two view types. See [this question](http://stackoverflow.com/questions/26245139/how-to-create-recyclerview-with-multiple-view-type) to see how to implement it. It might be a clue to achieve what you want. – Blo Dec 24 '15 at 02:10
  • Yes, I have done using that only currently. But one issue still lingers - how does FitBit manage to keep the header row sticking on the top of the screen even if we scroll? – Sid Dec 24 '15 at 10:16
  • 4
    You can try this [library](https://github.com/timehop/sticky-headers-recyclerview) You can setcustom layouts for the items and headers so I think this is excatly what you are looking for – Cilenco Jan 08 '16 at 10:44
  • Thanks! That answers it! – Sid Jan 08 '16 at 23:11

5 Answers5

6

You should use the concept of different view types using getItemViewType(int). Then on onCreateViewHolder(ViewGroup, int) you can check which type you should inflate/create.

Example:

@Override
public int getItemViewType(int position) {
    // you should return the view type, based on your own dynamic logic
}

@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
     switch (viewType) {
         // handle each view type accordingly
     }
}
Sevle
  • 3,109
  • 2
  • 19
  • 31
thiagolr
  • 6,909
  • 6
  • 44
  • 64
2

Use StickyHeaderRecyclerView library

It is very easy to use

Bhawna Raheja
  • 619
  • 4
  • 11
0

You can use the concept of multiple view types in your RecyclerView, Just by using getItemViewType(), and take care of the viewType parameter in onCreateViewHolder().

For example you can use below model:

    public class Data{
           int field1;
           float filed2;
           int rowType // 1,2,2,...N this will fill by you whenever you will    
                       //creating arraylist for your recyclerview
     }


    public class Custome Adapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {

    ArrayList<Data> mItems;

    class ViewHolderRowType1 extends RecyclerView.ViewHolder {
        ...
    }

    class ViewHolderRowType2 extends RecyclerView.ViewHolder {
        ...
    }

    ....
    class ViewHolderRowTypeN extends RecyclerView.ViewHolder {
        ...
    }

    @Override
    public int getItemViewType(int position) {
        return mItems.get(position).rowType; 
        //or
        //return positon%2; // This will based on your condition        
    }

    @Override
    public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
         switch (viewType) {
             case 0: return new ViewHolderRowType0(...);
             case 1: return new ViewHolderRowType1(...);
             ...
             case N: return new ViewHolderRowTypeN(...);
         }
    }

    @Override
    public void onBindViewHolder(RecyclerView.ViewHolder vh, int position) {

    //Just check which view type is going to bind and then fill the data accordingly in your rows


      if(vh instanceof ViewHolderRowType1){
       // Fill the data for first view type


      } else if (vh instanceof ViewHolderRowType2) {
       // Fill the data for second view type


      } else if (vh instanceof ViewHolderRowTypeN){
       // Fill the data for Nth view type


      }

    }

For your sticky "this view weak", you can add it at top of your RecyclerView and then handle it by scroll Event of RecyclerView

Lavekush Agrawal
  • 6,040
  • 7
  • 52
  • 85
0

There are two ways to implement such RecyclerView

  1. Add header in every layout and hide/show based on your requirement(preferable).
  2. Or use two different layouts for header and content(not preferable because it can cause problem in total count of items in adapter).

In your custom POJO / GetterSetter class, add one field for headerStatus(either boolean or int), to identify whether to show header or not.

Now in adapter override public int getItemViewType(int position).

static final int TYPE_ITEM = 0;
static final int TYPE_SEPARATOR = 1;
@Override
public int getItemViewType(int position) {
 if (mData.get(position).getHeaderStatus() == 0)
  return TYPE_ITEM;
 else
  return TYPE_SEPARATOR;
}

Now at the time of inflating the layout in getView() you can check the row type by

int rowType = getItemViewType(position);

For case 1, you need to visible the header and set appropriate data in it. For case 2, you need to inflate that header layout and add appropriate data in it.

Arth Tilva
  • 2,496
  • 22
  • 40
0

If you want to do it in "proper" way, without hacks, you should write your own LayoutManager, and handle those cases by hands. It is not as hard as it sounds, but will take some efforts.

Kaerdan
  • 1,180
  • 10
  • 9