Java 回收器视图-滚动时调整项目视图的大小(用于类似旋转木马的效果)
我需要创建一个垂直的回收视图,在这个视图中,屏幕中央的项目视图应该调整大小,以便在滚动时具有类似缩放的效果 我尝试过但没有成功的事情:Java 回收器视图-滚动时调整项目视图的大小(用于类似旋转木马的效果),java,android,performance,android-layout,android-recyclerview,Java,Android,Performance,Android Layout,Android Recyclerview,我需要创建一个垂直的回收视图,在这个视图中,屏幕中央的项目视图应该调整大小,以便在滚动时具有类似缩放的效果 我尝试过但没有成功的事情: 添加滚动侦听器并按位置在项目视图中循环,测量居中位置,然后更新居中视图的布局参数 RecyclerView不允许在滚动时计算项目的位置或更新视图。如果在onScrolled 当滚动状态为“空闲”或“正在结算”时,在onScrollStateChanged中更改居中项目视图的LayoutParams 仅在滚动已完成/即将完成后更新视图,而不是在执行项目滚动期
不允许在滚动时计算项目的位置或更新视图。如果在RecyclerView
onScrolled
onScrollStateChanged
中更改居中项目视图的LayoutParams
- 仅在滚动已完成/即将完成后更新视图,而不是在执行项目滚动期间更新视图
LayoutManager
,它将扩展默认的LayoutManager
- 据我所知,实现自定义
需要处理更多复杂的计算李>Layoutmanager
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;
}
}
}
公共类CenterZoomLayoutManager扩展了LinearLayoutManager{
私人最终浮动mShrinkAmount=0.15f;
专用最终浮点数mShrinkDistance=0.9f;
公共中心ZoomLayoutManager(上下文){
超级(上下文);
}
公共中心ZoomLayoutManager(上下文上下文、int方向、布尔反转){
超级(上下文、方向、反转);
}
@凌驾
public int scrollVerticallyBy(int-dy,RecyclerView.recyclerRecycler,RecyclerView.State){
int-orientation=getOrientation();
如果(方向==垂直){
int scrolled=super.scrollVerticallyBy(dy,recycler,state);
浮点中点=getHeight()/2.f;
浮点数d0=0.f;
浮点d1=mShrinkDistance*中点;
浮点数s0=1.f;
浮动s1=1.f—mShrinkAmount;
对于(int i=0;i
水平方向:
垂直方向:
你知道如何使它循环吗??我有10个项目的水平回收视图。我想无限滚动它。i、 e位置1将在所有项目完成后再次出现。@RonakThakkar我认为这样的技巧会起作用:@Krupal,你有没有想过如何在下一个可滚动项目中包含窥视?@KrupalShah,谢谢你的解决方案,但这似乎对不同的移动屏幕大小不起作用。我已经用不同的屏幕尺寸测试过了,在一些设备上,左右项目看起来很完美,而在一些设备上则不完美。“我在这里说的是水平列表。”穆罕默德·法罕说,“它似乎对我有用。”。你可以自己修改。嘿@Krupal Shah,你能帮我修改一下吗