2014-11-10 4 views
5

Я хочу сделать анимацию в RecyclerView, которая требует, чтобы у ребенка был больший z-индекс, чем у другого ребенка. Однако, когда я использовал метод bringToFront в ViewGroup, он не работал.bringToFront не работает в RecyclerView

Есть ли способ привести ребенка на фронт в RecyclerView?

ответ

4

Порядок детей контролируется LayoutManager. Построенные в LayoutManagers имеют собственный строгий порядок детей по соображениям производительности.

Текущая реализация bringToFront просто перемещает ребенка в конец списка детей, который не будет хорошо работать с существующими менеджерами макетов.

Если вы нацеливаетесь на Lollipop, вы можете использовать метод setElevation. Чтобы настроить таргетинг на более старые платформы, вам понадобится настраиваемый LayoutManager, который не будет полагаться на порядок детей.

+1

Спасибо, но обычай LayoutManager может вызвать некоторые сложности, мне удалось сделать некоторые хитрости, чтобы клонировать вид я хочу, чтобы оживить. – Juude

7

Действительно, bringToFront() не помогает; он просто изменяет порядок дочерних элементов в дочернем массиве его родителя, но он не меняет порядок воспроизведения детей.

Если вы используете API-21 или выше, вы можете просто изменить значение вида Z (view.setZ(..)), чтобы перенести его на передний план.

Ниже API-21 есть обратный вызов, который вы можете использовать: RecyclerView.ChildDrawingOrderCallback. С его помощью можно определить, дети порядка должны быть оказаны (Вы также можете использовать этот API-21 + в случае, если вам не нравится лишняя тень вы получите, изменив значение Z.)

. Пример:

final int indexOfFrontChild = rv.indexOfChild(desiredFrontView); 
rv.setChildDrawingOrderCallback(new RecyclerView.ChildDrawingOrderCallback() { 

    private int nextChildIndexToRender; 

    @Override 
    public int onGetChildDrawingOrder(int childCount, int iteration) { 
     if (iteration == childCount - 1) { 
      // in the last iteration return the index of the child 
      // we want to bring to front (and reset nextChildIndexToRender) 
      nextChildIndexToRender = 0; 
      return indexOfFrontChild; 
     } else { 
      if (nextChildIndexToRender == indexOfFrontChild) { 
       // skip this index; we will render it during last iteration 
       nextChildIndexToRender++; 
      } 
      return nextChildIndexToRender++; 
     } 
    } 
}); 
rv.invalidate(); 

в принципе, onGetChildDrawingOrder(...) будет называться childCount раз и в каждом iteration мы можем определить, какой ребенок, чтобы сделать (возвращая его индекс).

+1

Пробовал этот код. Сбой приложения после использования при попытке прокрутки RecyclerView. – 0101100101

+0

@ 0101100101, вы уверены, что ваш indexOfFrontChild находится в диапазоне [0, childCount-1]? Или спросить об этом по-другому, уверены ли вы, что ваш желаемыйFrontView является дочерним элементом вашего RecyclerView? –

+1

Оба да. Анимация действительно отлично работает с этим кодом, только прокручивая ее после этого. – 0101100101

0

Ответ, приведенный @Zsolt Safrany, основан на предположении, что обратный вызов всегда вызывается из итерации 0, что, как я проверял, неверно.

Здесь я отправляю рабочую реализацию, которая не ретранслируется на внешний счетчик.

//index of item you want to be displayed on top 
private int indexOfFrontChild = 2; 

    @Override 
     public int onGetChildDrawingOrder(int childCount, int iteration) { 
      int childPos = iteration; 
      //index must be in at least smaller than all children's 
      if (indexOfFrontChild < childCount) { 
       //in the last iteration we return view we want to have on top 
       if (iteration == childCount - 1) { 
        childPos = indexOfFrontChild; 
       }else if (iteration >= indexOfFrontChild) { 
        childPos = iteration + 1; 
       } 
      } 
      return childPos; 
     } 

В моем случае предметы были в состоянии изменить их высоту, чтобы 1 элемент мог взять весь экран. Так приятно, чтобы проверить, если indexOfFrontChild элемент отображаемый

if (indexOfFrontChild < childCount) 

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

  • Нет связанных вопросов^_^