回收站视图-滚动时调整项目视图的大小(适用于轮播效果) [英] Recycler view - resizing item view while scrolling (for carousel like effect)

查看:72
本文介绍了回收站视图-滚动时调整项目视图的大小(适用于轮播效果)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要创建一个垂直的回收站视图,在其中应调整屏幕中心的项目视图的大小,以在滚动时具有类似缩放的效果.

I need to create a vertical recyclerview in which item view in center of the screen should be resized to have zoom like effect while scrolling.

我尝试过但没用的东西:

Things I have tried but didn't work :

  1. 添加滚动侦听器并按位置循环浏览项目视图,测量居中位置,然后更新居中viewLayoutParams.

  • RecyclerView不允许在滚动时计算项目的位置或更新视图.如果在onScrolled
  • 中执行了此类操作,则会抛出IllegalStateException
  • RecyclerView won't let compute the position of items or update view while scrolling. It throws IllegalStateException if such operations are performed in onScrolled

在滚动状态为IDLESETTLING时,在onScrollStateChanged中更改居中项视图的LayoutParams.

Changing LayoutParams of centered item view in onScrollStateChanged while scrolling state is IDLE or SETTLING.

  • 仅在滚动完成/将要完成之后才更新视图,而不是在滚动项目时进行.

剩下的最后一个选项是实现自己的自定义LayoutManager,该自定义LayoutManager将扩展默认的LayoutManager.

The last option remained is implementing own custom LayoutManager that would extend default LayoutManager.

  • 据我所知,实现自定义Layoutmanager涉及处理许多需要处理的复杂计算.
  • As far as I know, implementing custom Layoutmanager involves dealing with a lot more complex computations that needs to handled.

任何其他解决方案或想法都将受到赞赏.

推荐答案

我发现关于SO的答案,水平完全相同的东西. Answer提供了扩展LinearLayoutManager的有效解决方案.我对其进行了一些修改,以适应垂直列表,并且可以正常工作.如果执行中有任何错误,请在评论中告知我.干杯!

I found this answer on SO, which did the exact same thing horizontally. Answer provides a working solution that extends LinearLayoutManager. I modified it a bit for also adapting vertical lists and it works. If there is any mistake in implementation, let me know in comments. Cheers!

自定义布局管理器:

public class CenterZoomLayoutManager extends LinearLayoutManager {

    private final float mShrinkAmount = 0.15f;
    private final float mShrinkDistance = 0.9f;

    public CenterZoomLayoutManager(Context context) {
        super(context);
    }

    public CenterZoomLayoutManager(Context context, int orientation, boolean reverseLayout) {
        super(context, orientation, reverseLayout);
    }


    @Override
    public int scrollVerticallyBy(int dy, RecyclerView.Recycler recycler, RecyclerView.State state) {
        int orientation = getOrientation();
        if (orientation == VERTICAL) {
            int scrolled = super.scrollVerticallyBy(dy, recycler, state);
            float midpoint = getHeight() / 2.f;
            float d0 = 0.f;
            float d1 = mShrinkDistance * midpoint;
            float s0 = 1.f;
            float s1 = 1.f - mShrinkAmount;
            for (int i = 0; i < getChildCount(); i++) {
                View child = getChildAt(i);
                float childMidpoint =
                        (getDecoratedBottom(child) + getDecoratedTop(child)) / 2.f;
                float d = Math.min(d1, Math.abs(midpoint - childMidpoint));
                float scale = s0 + (s1 - s0) * (d - d0) / (d1 - d0);
                child.setScaleX(scale);
                child.setScaleY(scale);
            }
            return scrolled;
        } else {
            return 0;
        }
    }

    @Override
    public int scrollHorizontallyBy(int dx, RecyclerView.Recycler recycler, RecyclerView.State state) {
        int orientation = getOrientation();
        if (orientation == HORIZONTAL) {
            int scrolled = super.scrollHorizontallyBy(dx, recycler, state);

            float midpoint = getWidth() / 2.f;
            float d0 = 0.f;
            float d1 = mShrinkDistance * midpoint;
            float s0 = 1.f;
            float s1 = 1.f - mShrinkAmount;
            for (int i = 0; i < getChildCount(); i++) {
                View child = getChildAt(i);
                float childMidpoint =
                        (getDecoratedRight(child) + getDecoratedLeft(child)) / 2.f;
                float d = Math.min(d1, Math.abs(midpoint - childMidpoint));
                float scale = s0 + (s1 - s0) * (d - d0) / (d1 - d0);
                child.setScaleX(scale);
                child.setScaleY(scale);
            }
            return scrolled;
        } else {
            return 0;
        }

    }
}

水平定向:

垂直放置:

这篇关于回收站视图-滚动时调整项目视图的大小(适用于轮播效果)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆