【问题标题】:Prevent ItemDecorator to add dividers to my viewtypes防止 ItemDecorator 向我的视图类型添加分隔符
【发布时间】:2020-06-28 16:49:18
【问题描述】:

我用 ConcatAdapter 制作了一个 recyclerview,想法是每个适配器都有 2 个视图类型,一个用于标题,一个用于项目,现在,当在所有这些适配器上应用带有 itemDecorator 的分隔器时,它应用于每个视图类型,但我不想将装饰器应用于所有视图类型,而是在内容视图类型之后

 //Merge all together
        val concatAdapter = ConcatAdapter(
            firstConcatAdapter,
            secondConcatAdapter,
            thirdConcatAdapter
        )

        val dividerItemDecorationInstance =
            DividerItemDecoration(requireContext(), LinearLayoutManager.VERTICAL)
        test_rv.addItemDecoration(dividerItemDecorationInstance)
        dividerItemDecorationInstance.setDrawable(
            ContextCompat.getDrawable(
                requireContext(),
                R.drawable.recycler_home_divider
            )!!
        )
        test_rv.layoutManager = LinearLayoutManager(requireContext())
        test_rv.adapter = concatAdapter

所以这里的 test_rv 是一个 recyclerview,我在这个 recyclerview 中膨胀了不同的适配器,在其中我显示了 UI 的不同自定义部分,每个适配器,firstConcatAdapter 等都有 2 个视图类型,它有一个标题,然后是项目,但我的输出是这样的

所以这里发生的事情是分隔线也适用于标题视图类型,我不希望它显示在那里,我只需要在所有视图都用它的视图类型膨胀后的分隔线

【问题讨论】:

    标签: android kotlin android-recyclerview android-adapter item-decoration


    【解决方案1】:

    您可以扩展 ItemDecoration 并使您的逻辑显示尊重项目类型的分隔符,假设您的项目类型为 (headeritem)

    import android.graphics.Canvas
    import android.graphics.Paint
    import androidx.recyclerview.widget.RecyclerView
    
    
    class HorizontalItemDecoration(
    color: Int,
    private val heightInPixels: Int) : RecyclerView.ItemDecoration() {
    
    private val paint = Paint()
    
     init {
      paint.color = color
      paint.isAntiAlias = true
     }
    
    override fun onDraw(c: Canvas, parent: RecyclerView, state: RecyclerView.State) {
    super.onDraw(c, parent, state)
    
    val left = parent.paddingLeft
    val right = parent.width - parent.paddingRight
    
    val childCount = parent.childCount
    for (i in 0 until childCount) {
      val child = parent.getChildAt(i)
    
      val params = child.layoutParams as RecyclerView.LayoutParams
    
      val top = child.bottom + params.bottomMargin
      val bottom = top + heightInPixels
      val adapterPosition = parent.getChildAdapterPosition(child)
      val viewType= parent.adapter.getItemViewType(adapterPosition )
      if (viewType == RowType.ITEM.ordinal) { // here you make check before drawing the divider where row type determine if this item is header or normal item
        c.drawRect(left.toFloat(), top.toFloat(), right.toFloat(), bottom.toFloat(), paint)
       }
      }
     }
    }
    

    行类型枚举

    enum class RowType {
    ITEM,
    HEADER;
    }
    

    使用ItemDecoration

    val dividerHeightInPixels = resources.getDimensionPixelSize(R.dimen.1sdp)
    val dividerItemDecoration = HorizontalItemDecoration(ContextCompat.getColor(requireContext(), R.color.divider_color), dividerHeightInPixels)
    recyclerView.addItemDecoration(dividerItemDecoration)
    

    【讨论】:

    • leftToFloat 是什么?
    • 只是一个错字,已修复
    • 所以在我的适配器中我需要使用枚举类而不是 private const val HEADER = 0 ?
    • 你可以使用它们中的任何一个
    • 因为我为 itemDecorator 使用了可绘制对象,你可以像问题一样更改构造函数以传递可绘制对象吗?谢谢
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-01-27
    • 2014-02-07
    • 2013-06-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-01-03
    相关资源
    最近更新 更多