【问题标题】:add list section headers with PagedListAdapter / PagedList使用 PagedListAdapter / PagedList 添加列表部分标题
【发布时间】:2019-03-27 12:36:47
【问题描述】:

我想使用android.arch.paging 组件在列表中添加标题。

通常这很容易,只需为 RecyclerView 适配器添加不同的类型来处理并从包含标题的项目创建一个新列表。

但是对于分页组件,我实际上是在处理来自SQL 查询的PagedListPositionalDataSource。是否可以中断这个并添加标题类型?

【问题讨论】:

  • 你好,找到新字符时你想要标题吗?
  • 我猜标题内容并不重要,因为它可能会根据列表而变化
  • 为所有项目添加不可见的标题,但仅显示所需项目的标题(另见:stackoverflow.com/a/53023782/5312102

标签: android android-paging


【解决方案1】:

我最终如何为感兴趣的人解决这个问题。

绑定数据的时候我也传入了前一项

  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)
  }

然后每个视图设置一个标题,只有在前一个项目没有相同标题时才会显示该标题。

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

2020 年 1 月 24 日更新

自从回答这个问题后,我已更改为使用自定义 ItemDecoration

class StickyHeaderDividerItem(
  context: Context,
  private val stickyHeaderCallbacks: StickyHeaderCallbacks
) : ItemDecoration() {

  private val headerHeight = context.resources.getDimensionPixelOffset(R.dimen.sticky_header_height)
  private var headerView: View? = null
  private var headerTextView: TextView? = null
  private var headerEndTextView: TextView? = null

  override fun getItemOffsets(outRect: Rect, view: View, parent: RecyclerView, state: State) {
    super.getItemOffsets(outRect, view, parent, state)

    val position = parent.getChildAdapterPosition(view)
    if (position >= 0 && stickyHeaderCallbacks.isHeader(position)) {
      outRect.top = headerHeight
    }
  }

  override fun onDrawOver(canvas: Canvas, parent: RecyclerView, state: State) {
    super.onDrawOver(canvas, parent, state)

    if (headerView == null) {
      headerView = (parent.inflate(R.layout.list_item_sticky_header)).apply {
        fixLayoutSize(this, parent)
      }
      headerTextView = headerView?.headerText
      headerEndTextView = headerView?.headerEndText
    }

    var previousHeader = ""
    parent.children.toList().forEach { child ->
      val position = parent.getChildAdapterPosition(child)
      val headerTitle = position.takeIf { it >= 0 }?.let(stickyHeaderCallbacks::headerTitle).orEmpty()
      val headerEndTitle = position.takeIf { it >= 0 }?.let(stickyHeaderCallbacks::headerTitleEnd)
      headerTextView?.text = headerTitle
      headerEndTextView?.text = headerEndTitle

      if ((previousHeader != headerTitle) || (position >= 0 && stickyHeaderCallbacks.isHeader(position))) {
        headerView?.let { drawHeader(canvas, child, it) }
        previousHeader = headerTitle
      }
    }
  }

  private fun drawHeader(canvas: Canvas, child: View, headerView: View) {
    canvas.run {
      save()
      translate(0F, maxOf(0, child.top - headerView.height).toFloat())
      headerView.draw(this)
      restore()
    }
  }

  private fun fixLayoutSize(view: View, parent: ViewGroup) {
    val widthSpec = View.MeasureSpec.makeMeasureSpec(parent.width, View.MeasureSpec.EXACTLY)
    val heightSpec = View.MeasureSpec.makeMeasureSpec(parent.height, View.MeasureSpec.UNSPECIFIED)
    val childWidth = ViewGroup.getChildMeasureSpec(widthSpec, parent.paddingStart + parent.paddingEnd, view.layoutParams.width)
    val childHeight = ViewGroup.getChildMeasureSpec(heightSpec, parent.paddingTop + parent.paddingBottom, view.layoutParams.height)
    view.measure(childWidth, childHeight)
    view.layout(0, 0, view.measuredWidth, view.measuredHeight)
  }
}



interface StickyHeaderCallbacks {

  fun isHeader(itemPosition: Int): Boolean
  fun headerTitle(itemPosition: Int): String
  fun headerTitleEnd(itemPosition: Int): String? = null
}

【讨论】:

  • 如果您连续有多个项目(例如画廊网格),您知道如何解决此问题吗?
  • 不抱歉。我最终完全删除了标题,因为它不是一个很好的实现。
  • 我尝试使标题与项目的大小相同,但它不起作用,现在我将尝试覆盖 AdapterDataObserver 像这里github.com/googlesamples/android-architecture-components/issues/…
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-03-24
  • 2015-11-05
  • 2013-09-24
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多