Recycler 查看项目装饰和视图高度

Recycler view item decoration and view elevation

我使用 recycler view decoration 在特定项目之前添加边距。

我的项目 - 主要是 MaterialCardView - 有一个重要的高度:16dp(感谢我们的 UI 人...)

允许使用

在项目视图容器外绘制立面图
android:clipChildren="false"
android:clipToPadding="false"

我的问题是:高度被回收器视图装饰截断了。

此处装饰码:

class TopSpacingItemDecoration(context: Context) : RecyclerView.ItemDecoration() {

    private val spacing = context.resources.getDimension(R.dimen.margin_before_section)

    override fun getItemOffsets(outRect: Rect, view: View, parent: RecyclerView, state: RecyclerView.State) {
        val position = parent.getChildAdapterPosition(view)
        val type = adapter.getItemViewType(position)

        if (type == adapter.SPECIFIC_TYPE || other conditions) {
            outRect.set(0, spacing.toInt(), 0, 0)
        }
    }
}

看起来像:

仅供参考:我不想管理项目的边距,因为回收站视图顺序是动态的

知道如何解决这个问题吗?

您正在使用 ItemDecorations 来做一些它们不适合做的事情,但您不想使用正确的东西,现在您想破解一个解决方案? (我做对了吗?)

在你解开这个谜语的过程中,我会给你我的 0.02c:

  1. ItemDecorations 的设计目的不是为了做您希望它们做的事情,因此您会看到这些 side-effects。
  2. ItemDecorations 是 RecyclerView 为您提供 "decorate" 视图的方式,通过 canvas 和几毫秒的时间在屏幕上绘制一些东西,完全脱离 View/Layout/Measure 引擎。
  3. 由于 "dynamic order",您明确禁止使用项目边距(和填充?)。我不完全确定这与命令有什么关系,但我不能在这方面与你战斗;什么顺序?商品订单?订单与边距或间距有什么关系? (我确定有原因,您没有列出)。 订单将如何影响这一点? margins/spacing 是不是因为物品不同所以两边不均匀?我推断这一点,因为你在 if (item == type_xxx) {} 中提供了一个小提示,所以我假设你正在使用某种 itemType 在你的回收站视图中呈现不同的视图,现在你想为这些项目添加一些动态边距,基于他们的邻居。

我假设这一切。

回答:您不能在 ItemDecorator 的视图边界之外绘制,因为它很酷,传递给它的 Canvas(因此它可以绘制)已经计算并受到 Android measure/layout 引擎。

另外:

android:clipChildren="false"
android:clipToPadding="false"

有 side-effects(性能方面,这根本不是很好)。

撇开性能不谈,您根本不能(或者更确切地说,不应该!)尝试这样做。装饰并不意味着是一张 "free for all draw wherever you want" 卡片。 我建议您在项目视图 and/or recyclerview 中提供适当的 padding/margin。它们可以处理密度像素,并在通过资源提供时考虑构建变体和风格(例如 dimens.xml)。

这些 技术 中的

None 将可供物品装饰者使用。但是如果你也忽略了代码分离、单一职责原则、控制反转这些行话,你还是做不到,因为你的canvas是为你计算好的,你的梦想也是在屏幕上的任意位置绘图。

(好吧,你 可以 在任何地方画画,但这不会推送其他视图,你只是在内容之上画画,而不是触摸它)。