我使用回收器 View 装饰在特定项目之前添加边距。
我的项目 - 主要是 MaterialCardView - 有一个重要的高度:16dp(感谢我们的 UI 人员...)
允许在 item view container 之外绘制立面图
android:clipChildren="false"
android:clipToPadding="false"
我的问题是:高度被回收器 View 装饰截断了。
这里装饰代码:
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:
- ItemDecorations 并非设计用于执行您希望它们执行的操作,因此您会看到这些副作用。
- ItemDecorations 是 RecyclerView 为您提供“装饰” View 的机会,方法是使用 Canvas 和几毫秒的时间在屏幕上绘制内容,完全脱离 View /布局/测量引擎。
- 由于“动态顺序”,您特别禁止使用项目边距(和填充?)。我不完全确定这与命令有什么关系,但我不能在这方面与你战斗;什么顺序?商品订单?订单与边距或间距有什么关系? (我确定有原因,您没有列出)。
订单将如何影响这一点?由于项目不同,不同边的边距/间距是否不均匀?我推断这一点,因为您在
if (item == type_xxx) {}
中提供了一个小提示,所以我假设您正在使用某种 itemType 在回收站 View 中呈现不同的 View ,现在你想根据它们的邻居为这些项目添加一些动态边距。
我假设这一切。
回答:您不能从 ItemDecorator 绘制 View 边界之外,因为它很酷,传递给它的 Canvas(因此它可以绘制)已经由 Android 测量/布局引擎计算和约束。
还有:
android:clipChildren="false"
android:clipToPadding="false"
有副作用(性能方面,这一点都不好)。
撇开性能不谈,您根本不能(或者更确切地说,不应该!)尝试以这种方式进行。装饰并不意味着是一张“随心所欲免费抽取”的卡片。 我建议您在项目 View 和/或 recyclerview 中提供适当的填充/边距。它们可以处理密度像素,并在通过资源(例如 dimens.xml)提供时考虑构建变体和风格。
这些技术都不适用于项目装饰器。但是如果你也忽略了代码分离、单一职责原则、控制反转这些行话,你还是做不到,因为你的 Canvas 是为你预先计算好的,你的 Canvas 上的任何地方的梦想也是如此。屏幕。
(好的,您可以在任何地方绘制,但这不会推送其他 View ,您只是在内容之上绘制,而不是触摸它)。
关于android - Recycler 查看项目装饰和 View 高度,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56524889/