8

Мне нужно создать вертикальную переработку, при которой вид элемента в центре экрана должен быть изменен, чтобы иметь эффект увеличения как при прокрутке.Вид ресайклера - изменение размера элемента при прокрутке (для эффекта карусели)

Вещи я пытался, но не получилось:

  1. Добавление прокрутки слушателя и циклически представления элементов по позиции, измерение центрального положения, то при обновлении LayoutParams центрированной view.

    • RecyclerView не позволяет вычислять позицию элементов или обновлять вид во время прокрутки. Это бросает IllegalStateException если такие операции выполняются в onScrolled
  2. изменяющегося LayoutParams центрированных зрения элемента в onScrollStateChanged при прокрутке состояния является IDLE или SETTLING.

    • Это обновление только после того, как прокрутка была/будет завершена, а не во время прокрутки элементов.
  3. Последний вариант остался реализации собственных пользовательских LayoutManager что бы продлить по умолчанию LayoutManager.

    • Насколько я знаю, реализация пользовательского Layoutmanager предполагает работу с более сложными вычислениями, которые необходимо обрабатывать.

Любые другие решения или идеи будут оценены.

ответ

24

Я нашел this answer on SO, который сделал то же самое по горизонтали. Ответ дает рабочее решение, которое расширяет LinearLayoutManager. Я немного изменил его для адаптации вертикальных списков, и он работает. Если есть какая-либо ошибка в реализации, дайте мне знать в комментариях. Ура!

Пользовательские Layout Manager:

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; 
     } 

    } 
} 

С горизонтальной ориентации: enter image description here

с вертикальной ориентацией:

enter image description here

+0

вы знаете, как сделать это циклическая ?? У меня есть горизонтальный рециклинг с 10 элементами. Я хочу прокрутить его бесконечно. i.e позиция 1 снова появится после завершения всех пунктов. –

+0

@RonakThakkar Я думаю, что такие трюки будут работать: https://stackoverflow.com/a/45114415/3830694 –

Смежные вопросы