[英]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.