bringToFront在RecyclerView中不起作用

时间:2014-11-10 12:35:47

标签: android android-layout android-recyclerview

我想在RecyclerView制作动画,要求孩子拥有比其他孩子更大的z指数。但是,当我在bringToFront中使用ViewGroup方法时,它无效。

有没有办法让孩子站在RecyclerView

前面

3 个答案:

答案 0 :(得分:8)

确实,bringToFront()没有帮助;它只是更改其父级子数组中子项的顺序,但它不会更改子项的呈现顺序。

如果您使用的是API-21或更高版本,则只需更改视图的Z值(view.setZ(..))即可将其置于最前面。

在API-21下面有一个可以使用的回调:RecyclerView.ChildDrawingOrderCallback。有了它,您可以定义子项应该呈现的顺序。(如果您不喜欢通过更改Z值获得的额外阴影,也可以使用API​​-21 +。)

示例:

final int indexOfFrontChild = rv.indexOfChild(desiredFrontView);
rv.setChildDrawingOrderCallback(new RecyclerView.ChildDrawingOrderCallback() {

    private int nextChildIndexToRender;

    @Override
    public int onGetChildDrawingOrder(int childCount, int iteration) {
        if (iteration == childCount - 1) {
            // in the last iteration return the index of the child 
            // we want to bring to front (and reset nextChildIndexToRender)  
            nextChildIndexToRender = 0;  
            return indexOfFrontChild;
        } else {
            if (nextChildIndexToRender == indexOfFrontChild) {
                // skip this index; we will render it during last iteration
                nextChildIndexToRender++;
            }
            return nextChildIndexToRender++;
        }
    }
});
rv.invalidate();

基本上,onGetChildDrawingOrder(...)将被称为childCount次,并且在每个iteration中我们可以指定要呈现的子项(通过返回其索引)。

答案 1 :(得分:5)

子项的顺序由LayoutManager控制。由于性能原因,内置的LayoutManagers有自己严格的子命令。

bringToFront的当前实现只是将孩子移动到子列表的末尾,这对于现有的LayoutManagers来说不会很好。

如果您定位Lollipop,则可以使用setElevation方法。 要定位较旧的平台,您需要一个不依赖于子级顺序的自定义LayoutManager。

答案 2 :(得分:0)

@Zsolt上面的回答Safrany基于假设回调总是从迭代0调用,而我测试的不是真的。

这里我发布的工作实现不会在外部计数器上传递。

//index of item you want to be displayed on top
private int indexOfFrontChild = 2;

  @Override
        public int onGetChildDrawingOrder(int childCount, int iteration) {
            int childPos = iteration;
            //index must be in at least smaller than all children's
            if (indexOfFrontChild < childCount) {
                //in the last iteration we return view we want to have on top
                if (iteration == childCount - 1) {
                    childPos = indexOfFrontChild;
                }else if (iteration >= indexOfFrontChild) {
                    childPos = iteration + 1;
                }
            }
            return childPos;
        }

在我的情况下,物品能够改变它们的高度,因此1个项目可以占据整个屏幕。因此,检查indexOfFrontChild项是否可显示是很好的

 if (indexOfFrontChild < childCount)