簡體   English   中英

Recycler視圖 - 滾動時調整項目視圖的大小(對於旋轉木馬效果)

[英]Recycler view - resizing item view while scrolling (for carousel like effect)

我需要創建一個垂直的Recyclerview,其中應調整屏幕中心的項目視圖,以便在滾動時具有縮放效果。

我嘗試但沒有奏效的事情:

  1. 添加滾動偵聽器並按位置循環瀏覽項目視圖,測量居中位置,然后更新居中view LayoutParams

    • RecyclerView不會在滾動時計算項目的位置或更新視圖。 如果在onScrolled中執行此類操作,則拋出IllegalStateException
  2. 在滾動狀態下更改onScrollStateChanged中居中項目視圖的LayoutParamsIDLESETTLING

    • 僅在滾動已經/將要完成之后才更新視圖,而不是在滾動項目期間執行。
  3. 剩下的最后一個選項是實現自定義的LayoutManager ,它將擴展默認的LayoutManager

    • 據我所知,實現自定義Layoutmanager涉及處理需要處理的更復雜的計算。

任何其他解決方案或想法將不勝感激。

在SO上找到了這個答案 ,它在橫向上做了完全相同的事情。 Answer提供了一個擴展LinearLayoutManager的工作解決方案。 我修改了一下以適應垂直列表並且它可以工作。 如果實施中有任何錯誤,請在評論中告訴我。 干杯!

自定義布局管理器

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;
        }

    }
}

水平方向: 在此輸入圖像描述

垂直方向:

在此輸入圖像描述

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM