[英]Recycler view - resizing item view while scrolling (for carousel like effect)
我需要創建一個垂直的Recyclerview,其中應調整屏幕中心的項目視圖,以便在滾動時具有縮放效果。
我嘗試但沒有奏效的事情:
添加滾動偵聽器並按位置循環瀏覽項目視圖,測量居中位置,然后更新居中view
LayoutParams
。
RecyclerView
不會在滾動時計算項目的位置或更新視圖。 如果在onScrolled
中執行此類操作,則拋出IllegalStateException
在滾動狀態下更改onScrollStateChanged
中居中項目視圖的LayoutParams
是IDLE
或SETTLING
。
剩下的最后一個選項是實現自定義的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.