How to add date separators in recycler view using

2019-04-12 08:48发布

问题:

After a lot of searching, I know its possible with regular adapter, but I have no idea how to do it using Paging Library. I don`t need code just a clue.

Example

回答1:

To add separators, you essentially have 2 options:

  1. View-based, you explicitly include separators as an 'item' in the list and define a new viewtype for those separators. Allows the list to re-use the separator views but means you need to take the separators into account when defining the data.
  2. Data-based, each item actually has a separator view, but it only shows on specific items. Based on some criteria you show or hide it whilst binding the view-holder.

For the paging library only option 2 is viable since it only partially loads the data and inserting the separators becomes much more complicated. You will simply need to figure out a way to check if item x is a different day than item x-1 and show/hide the date section in the view depending on the result.



回答2:

As mentioned here, Paging Library works with PagedListAdapter. And PagedListAdapter extends from RecyclerView.Adapter, so you can do this simply like in Recyclerview (example). Just in two words - you need to use different view types for your date headers and content items.



回答3:

When binding the data pass in the previous item as well

  override fun onBindViewHolder(holder: ViewHolder, position: Int) {
    val item = getItem(position)
    val previousItem = if (position == 0) null else getItem(position - 1)
    holder.bind(item, previousItem)
  }

Every view then sets a header, which is only made visible if the previous item doesn't have the same header.

    val previousHeader =  previousItem?.name?.capitalize().first()
    val header = item?.name?.capitalize()?.first()
    view.cachedContactHeader.text = header
    view.cachedContactHeader.isVisible  = previousHeader != header


回答4:

Kiskae's answer is excellent and for your case option 2 probably works well.

In my case I wanted to have one additional item that wasn't in the database, like this:

  • Show all
  • Item 1
  • Item 2

It needed to be clickable as well. There's the usual way of overriding getItemCount to return +1 and offsetting positions for the other methods.

But I stumbled on another way that I haven't seen documented yet that might be useful for some cases. You might be able to incorporate additional elements into your query using union:

@Query("select '' as name, 0 as id " +
        "union " +
        "select name, id from user " +
        "order by 1 asc")
DataSource.Factory<Integer, User> getAllDataSource();

That means the data source actually returns another item in the beginning, and there's no need to adjust positions. In your adapter, you can check for that item and handle it differently.

In your case the query would have to be different but I think it would be possible.