Intereting Posts
Проблемы с показом alertdialog в фрагменте андроида Как включить инспекцию после отключения в Android Studio? Как я могу получить доступ к моему локальному хосту через телефон Android? Android: Создать случайный цвет при нажатии? Не удалось найти com.google.android.gms: play-services: 3.1.59 3.2.25 4.0.30 4.1.32 4.2.40 4.2.42 4.3.23 4.4.52 5.0.77 5.0.89 5.2.08 6.1. 11 6.1.71 6.5.87 Каков наилучший способ разработки кросс-мобильного приложения с поддержкой Bluetooth? Как использовать OpenCL на Android? Нет необходимости регистрировать базовый класс активности в манифесте? Изменить цвет границы формы во время выполнения Исключить тестовое устройство из журнала Firebase Analytics Сравнение двух строк не работает в android Получить информацию об устройстве (например, продукт, модель) из команды adb SetRepeating () AlarmManager повторяет через 1 минуту независимо от того, какое время установлено (5 секунд в этом случае, API 18+) «Недостаточно места для хранения», даже в памяти устройства много свободного места Android: TextView: удаление интервала и отступов сверху и снизу

Как получить смещение в 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 который проходит.