java - para - trucos habbo
Vista del reciclador: cambiar el tamaƱo de la vista del elemento mientras se desplaza(para efectos de carrusel) (1)
Necesito crear una vista de reciclaje vertical en la que la vista del elemento en el centro de la pantalla deba cambiar de tamaño para tener un efecto de zoom al desplazarse.
Cosas que he probado pero no funcionaron:
Agregando un detector de desplazamiento y repasando las vistas de elementos por posición, midiendo la posición centrada y luego actualizando los
LayoutParams
de laview
centrada.-
RecyclerView
no permite calcular la posición de los elementos o actualizar la vista mientras se desplaza.IllegalStateException
si tales operaciones se realizan enonScrolled
-
El cambio de
LayoutParams
de la vista del elemento centrado enonScrollStateChanged
durante el estado de desplazamiento esIDLE
oSETTLING
.- El hecho de que solo se actualice la vista después de que se haya completado el desplazamiento, no se realiza durante el desplazamiento en los elementos.
La última opción que queda es implementar su propio
LayoutManager
personalizado que extendería elLayoutManager
predeterminado.- Por lo que sé, la implementación de
Layoutmanager
personalizado implica tratar con cálculos mucho más complejos que deben manejarse.
- Por lo que sé, la implementación de
Cualquier otra solución o idea será apreciada.
Encontré esta respuesta en SO , que hizo exactamente lo mismo horizontalmente. Answer proporciona una solución de trabajo que extiende LinearLayoutManager
. Lo modifiqué un poco para adaptar también las listas verticales y funciona. Si hay algún error en la implementación, hágamelo saber en los comentarios. ¡Aclamaciones!
Administrador de diseño personalizado:
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;
}
}
}
con orientación vertical: