RecyclerView / SnapHelper - Как установить переменное положение карт, чтобы они выглядели по-разному в зависимости от положения - PullRequest
0 голосов
/ 24 мая 2019

Я новичок в Android и, следовательно, RV, и я пытаюсь достичь макета, где первая и последняя карты не центрированы и вместо этого показывают больше карт после и до них.Может быть, в этом случае я вижу 16dp для вторых карт и то же самое для предпоследней карты, которая делает первую и последнюю карту не центрированными.Но 8dp каждая для остальных карт, поэтому промежуточные карты отображаются по центру.Может быть, каким-то образом использовать itemDecoration для 2-й и предпоследней карт.

enter image description here

Мне удалось показать части следующих и предыдущих карт, следуя тому, чтоздесь предлагается, но это только центрирует все карты одинаково: Как показать часть следующей / предыдущей карты RecyclerView

Я пытался переопределить getItemOffsets, но он срабатывает каждый раз, когда я прокручиваю к первой илиПоследняя карта и перемещает 2-ю и 2-ю к последней карте неправильно, а также не центрирует их правильно, когда я прокручиваю к ним.

  public static class MyItemDecoration extends RecyclerView.ItemDecoration {

    @Override
    public void getItemOffsets(@NonNull Rect outRect, @NonNull View view, @NonNull RecyclerView parent, @NonNull RecyclerView.State state) {
      super.getItemOffsets(outRect, view, parent, state);

      final int itemPosition = parent.getChildAdapterPosition(view);
      if (itemPosition == RecyclerView.NO_POSITION) {
        return;
      }

      final int itemCount = state.getItemCount();
      if (itemCount > 0 && itemPosition == 1) {
        outRect.left -= 16;
        outRect.right -= 16;
      }

      else if (itemCount > 0 && itemPosition == itemCount - 1) {
        outRect.left += 16;
        outRect.right += 16;
      }
    }
  }

Настройка RV

 SnapHelper snapHelper = new PagerSnapHelper();
        RecyclerView rv = getBinding().rv;
        rv.setOnFlingListener(null);
        snapHelper.attachToRecyclerView(rv);

1 Ответ

1 голос
/ 29 мая 2019

PagerSnapHelper центрирует элементы RecyclerView , включая декорации, поэтому, если ширина декораций не сбалансирована, они не всегда будут центрированы.Это может быть то, что вы видите.

Попробуйте следующее для украшения.Этот код применяет художественное оформление полной ширины к началу первого элемента и концу последнего элемента;в противном случае используется половина декоративной ширины.Настраивая декорации таким образом, вы центрируете элементы, которые сбалансировали левую и правую декорации.

DividerItemDecoration decoration =
        new DividerItemDecoration(getApplicationContext(), HORIZONTAL) {
            private int mDecorationWidth = (int) (getResources().getDisplayMetrics().density * 8);

            @Override
            public void getItemOffsets(Rect outRect, View view, RecyclerView parent,
                                       RecyclerView.State state) {
                final int pos = parent.getChildAdapterPosition(view);
                if (pos == RecyclerView.NO_POSITION) {
                    return;
                }
                if (pos == 0) {
                    outRect.set(mDecorationWidth, 0, mDecorationWidth / 2, 0);
                } else if (pos == parent.getAdapter().getItemCount() - 1) {
                    outRect.set(mDecorationWidth / 2, 0, mDecorationWidth, 0);
                } else {
                    outRect.set(mDecorationWidth / 2, 0, mDecorationWidth / 2, 0);
                }
            }
        };

Вот видео, показывающее результаты с серыми вертикальными разделителями.

enter image description here

Если у вас уже есть украшения, работающие к вашему удовлетворению, вы можете переопределить calculateDistanceToFinalSnap() в PagerSnapHelper , чтобы центрировать все представления, кроме первого и последнего, следующим образом.См. расчетное сопротивление финала () .Как только PageSnapHelper идентифицирует целевой вид для привязки, вызывается calculatedistancetofinalsnap(), чтобы определить, сколько пикселей нужно переместить для выполнения привязки.Здесь мы перемещаем достаточно пикселей для центрирования вида (без декораций) в RecyclerView . PageSnapHelper делает правильные вещи для первого и последнего элементов, поэтому мы просто вызываем супер для них.

PagerSnapHelper pagerSnapHelper = new PagerSnapHelper() {  

    @Override  
  public int[] calculateDistanceToFinalSnap(@NonNull RecyclerView.LayoutManager layoutManager,  
                                              @NonNull View targetView) {  
        LinearLayoutManager lm = (LinearLayoutManager) layoutManager;  
        int pos = mRecycler.getChildAdapterPosition(targetView);  
        // If first or last view, the default implementation works.  
  if (pos == 0 || pos == lm.getItemCount() - 1) {  
            return super.calculateDistanceToFinalSnap(layoutManager, targetView);  
        }  
        // Force centering in the view without its decorations. 
        // targetCenter is the location of the center of the view we want to center. 
        int targetCenter = targetView.getLeft() + targetView.getWidth() / 2;  
        // Distance is the number of pixels to move the target so that its center
        // lines up with the center of the RecyclerView (mRecycler.getWidth() / 2)       
        int distance = targetCenter - mRecycler.getWidth() / 2;  
        return new int[]{distance, 0};  
    }  
};

В любом случае будет работать.

...