Intereting Posts
Использование текстового представления Android в качестве метки и значения Центрировать две кнопки по горизонтали Android – OnDateChangedListener – как вы это устанавливаете? Автоматически разрешает сборку Android Ошибка: пиксели кадра должны быть сплошными или прозрачными (не промежуточными альфа). – Найден в пикселе # 4 вдоль верхнего края Как объединить данные с помощью Android Volley Как вы можете получить адрес электронной почты пользователя Android? Не удается найти файл сценария «C: \ res \ windows \ zip.js» в Phonegap (windows) Проблемы с EditText и мягкой клавиатурой в фрагменте GreenRobot Ошибка EventBus в фрагментах: подписчиков, зарегистрированных для класса событий Специальная цифровая клавиатура Android Пакета R не существует Как получить высоту ActionBar? Что это предупреждение: Игнорирование атрибута InnerClasses для анонимного внутреннего класса, который не связан с атрибутом EnclosingMethod Eclipse: как восстановить настройки по умолчанию в перспективе? Инициализировать MapFragment программно с помощью Maps API v2

Как получить смещение в RecyclerView ItemDecorator

Я написал два ItemDecorator для RecyclerView . Каждый добавляет некоторое верхнее смещение в getItemOffsets() . Скажем:

  • Первый декоратор добавляет верхнее смещение 20dp
  • Второй декатор добавляет верхнее смещение 30dp

Теперь, когда я добавляю оба из них в RecyclerView , каждый элемент правильно смещается на 50dp, это хорошо.

Но здесь возникает вопрос: как мне получить это смещение в onDraw / onDrawOver ?

Обычно декораторы рисуют свои вещи, пересекая parent.getChildAt(i) и получая child.getTop() например, чтобы рисовать над дочерним видом RecyclerView .

Но в этом случае это приведет к смешению рисунка другого декоратора, потому что он также будет использовать child.getTop() .

Поэтому на данный момент кажется, что оба декоратора должны знать друг о друге и друг друга.

Я что-то упустил? Надеюсь, я.

EDIT: Я сообщил о проблеме на трекер для Android, и, похоже, это будет сработано. Постарайтесь отслеживать прогресс: https://code.google.com/p/android/issues/detail?id=195746

Solutions Collecting From Web of "Как получить смещение в RecyclerView ItemDecorator"

Tl; dr Нет, вы ничего не пропустили. Но вы можете получить значения, необходимые в getItemOffsets , хотя это кажется немного грязным для меня.

В принципе, есть только один способ получить украшенную высоту, LayoutManager.getDecoratedTop(); от управления украшениями: LayoutManager.getDecoratedTop();

OnDraw

В onDraw вы получаете весь холст recyclerView, c.getClipBounds() не содержит никакой информации. Хотя javadoc добавления декораций говорит, что украшения должны просто рисовать с их границами.

Кроме того, получение parent.getLayoutManager().getDecoratedTop() даст вам одинаковые значения в каждом украшении, так как уже слишком поздно здесь, эти значения предназначены для макетирования.

Мы слишком поздно, макетирование сделано, и мы его пропустили.

getItemOffsets

Обратите внимание, что я тестировал следующее с LinearLayoutManager и он мог бы также не работать с другими (наиболее определенно не с большинством пользовательских). Поскольку я полагаюсь на измерение происходящего между этими вызовами, которое не задокументировано, данное решение может сломаться с некоторой будущей версией.

Я просто почувствовал, что мне нужен этот отказ. Я нашел рабочее решение (смотри mOffset ):

 @Override public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) { mOffset = parent.getLayoutManager().getTopDecorationHeight(view); outRect.set(0, 10, 0, 0); } 

Это работает, потому что recyclerview при вычислении общей вставки дочернего элемента обновляет локальную переменную LayoutParams пакета представлений . Хотя мы не можем получить доступ к самой переменной параметров компоновки, вызов getTopDecorationHeight фактически использует (в настоящее время) грязную вставку, что дает нам правильное значение.
Следовательно, вы можете получить смещение предыдущих украшений, прежде чем применять свои собственные!

Чтобы применить его, просто удалите другие украшения, компенсирующие при рисовании:

 c.drawRect(child.getLeft() + child.getTranslationX(), mOffset + layoutManager.getDecoratedTop(child) + child.getTranslationY(), child.getRight() + child.getTranslationX(), child.getBottom() + child.getTranslationY(), paint); 

Это на самом деле применит другое смещение украшений, а затем нарисует ваше собственное из правильного верха.

Некоторые проблемы

Это теперь базовое, рабочее решение для стандартного использования . НО . Если у вас есть разные смещения в зависимости от элемента VIEW_TYPE или положения адаптера, все становится сложным.

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

Для этого вы можете либо добавить какой-то пользовательский тег с помощью view.setTag(key, object) либо сделать что-то подобное с объектом RecyclerView.State который проходит.