我为ItemDecorator
写了两个RecyclerView
。每个都在getItemOffsets()
中添加一些顶部偏移量。让我们说:
现在,当我将它们都添加到RecyclerView
时,每个项目都正确地偏移了50dp,这很好。
但是问题出现了:
如何在onDraw
/ onDrawOver
?
通常,装饰者通过遍历parent.getChildAt(i)
内容并获取child.getTop()
来绘制他们的内容,例如绘制上面RecyclerView
的子视图。
但在这种情况下,这样做会混淆其他装饰器的绘制,因为它也会使用child.getTop()
。
所以目前两个装饰师似乎都需要了解彼此和彼此的身高。
我在这里遗漏了什么吗?我希望我是。
编辑: 我向Android问题跟踪器报告了一个问题,似乎这将会有效。明确它以跟踪进度: https://code.google.com/p/android/issues/detail?id=195746
答案 0 :(得分:14)
tl; dr 不,你没有遗漏任何东西。但你可以获得getItemOffsets
所需的值,虽然它对我来说似乎有点脏。
基本上只有一个选项来获取装饰高度而不是自己管理装饰:LayoutManager.getDecoratedTop();
<强>的onDraw 强>
在onDraw
中,您获得了recyclerView的整个画布,c.getClipBounds()
不包含任何信息。虽然添加装饰的javadoc说装饰应该只用他们的界限绘制。
另外,获取parent.getLayoutManager().getDecoratedTop()
会在每个装饰中给出相同的值,因为这里已经太晚了,这些值是用于布局目的。
我们太晚了,布局已经完成,我们错过了它。
<强> getItemOffsets 强>
请注意,我使用
LinearLayoutManager
对以下内容进行了测试,但它可能与其他人无法合作(绝大多数都不适用于大多数自定义内容)。由于我依赖于测量这些未记录的调用之间发生的事情,因此给定的解决方案可能会破坏未来的版本。
我觉得我需要免责声明。我找到了一个有效的解决方案(观看mOffset
):
@Override
public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {
mOffset = parent.getLayoutManager().getTopDecorationHeight(view);
outRect.set(0, 10, 0, 0);
}
这很有效,因为在计算孩子的总插入时,recyclerview是updating the views package local LayoutParams variable。虽然我们无法访问布局参数变量本身,但调用getTopDecorationHeight实际上使用了(当前)脏插图,为我们提供了正确的值。
因此,您可以在应用之前获得先前装饰的偏移量!
要应用它,只需在绘制装饰时移除其他装饰偏移:
c.drawRect(child.getLeft() + child.getTranslationX(),
mOffset + layoutManager.getDecoratedTop(child) + child.getTranslationY(),
child.getRight() + child.getTranslationX(),
child.getBottom() + child.getTranslationY(), paint);
这实际上会应用其他装饰偏移,然后从正确的顶部绘制自己的装饰。
有些问题
现在,这是默认用例的基本工作解决方案。的 BUT 即可。如果根据项目VIEW_TYPE或适配器位置有不同的偏移量,那么事情会变得棘手。
您将复制逻辑并为各种视图类型保留各种偏移量,或者您必须为每个视图或视图类型存储/检索偏移量。
为此,您可以使用view.setTag(key, object)
添加一些自定义标记,或者使用传递的RecyclerView.State
对象执行类似操作。