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
LayoutParamsde laviewcentrada.-
RecyclerViewno permite calcular la posición de los elementos o actualizar la vista mientras se desplaza.IllegalStateExceptionsi tales operaciones se realizan enonScrolled
-
El cambio de
LayoutParamsde la vista del elemento centrado enonScrollStateChangeddurante el estado de desplazamiento esIDLEoSETTLING.- 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
LayoutManagerpersonalizado que extendería elLayoutManagerpredeterminado.- Por lo que sé, la implementación de
Layoutmanagerpersonalizado 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: