Получить номер столбца, где представление находится на GridLayoutManager - PullRequest
1 голос
/ 26 июня 2019

У меня есть различные типы элементов, отображаемых в RecyclerView с использованием GridLayoutManager с динамическим номером столбца.Проблема в том, что у меня есть RecyclerView.ItemDecoration, который должен применяться только для, скажем, Type A элементов.это RecyclerView.ItemDecoration добавляет поле слева / начало для тех элементов в левом столбце, а поле справа / конец - для этих элементов в правом столбце.По сути, элементы выглядят немного более центрированными и растянутыми (это используется в планшетном / альбомном режиме).Сетка RecyclerView выглядит примерно так:

| A | | A |
| A | | A |
   | B |
| A | | A |
| A | | A |
   | B |
| A | | A |

ItemDecoration выглядит следующим образом:

class TabletGridSpaceItemDecoration(private val space: Int) : RecyclerView.ItemDecoration() {

    override fun getItemOffsets(outRect: Rect, view: View, parent: RecyclerView, state: RecyclerView.State) = with(outRect) {
        val isTypeAItemLayout = view.findViewById<ConstraintLayout>(R.id.type_a_item_container) != null

        if (isTypeAItemLayout) {
            val adapterPosition = parent.getChildAdapterPosition(view)

            if (adapterPosition % 2 == 0) {
                left = space
                right = 0
            } else {
                left = 0
                right = space
            }
        }
    }
}

Проблема этого декоратора в том, что после первого элемента type Bв списке индексы запутались для следующих type A пунктов.Таким образом, первый элемент после B в соответствии с приведенным примером будет иметь adapterPosition == 5, поэтому в соответствии с TabletGridSpaceItemDecoration необходимо добавить пометку справа, что неверно.

  • Iпопытался иметь HashMap, чтобы сохранить adapterPosition и реальную позицию элемента, то есть позицию, которую он будет иметь на адаптере, игнорируя не type A элементы.У этого есть некоторые другие проблемы, я не буду вдаваться в подробности, но это не совсем правильный способ сделать это.

  • Еще одна вещь, которую я пробовал, это проверить местоположение нана экране вида (больше слева или справа) будет применено оформление предмета.Проблема в том, что при запуске этого декоратора представление еще не отображалось.Добавление ViewTreeObserver.OnGlobalLayoutListener к представлению бесполезно, так как к моменту представления представление оформление элемента уже применено, что не влияет на представление.

Что яЯ хотел бы проверить, находится ли элемент в «столбце 0» или «столбце 1» и, соответственно, добавить поле.

Я не знаю, как это возможно, и не сделалнайдите способ сделать это, взглянув на то, что предоставляет GridLayoutManager, к которому можно получить доступ parent.layoutManager as GridLayoutManager.

Есть идеи?Спасибо

1 Ответ

1 голос
/ 26 июня 2019

Я делюсь этим как ответом, потому что это слишком долго для комментария. Дайте мне знать результат, а затем я удаляю, если не работает.

Также, извините, что делюсь на Java .. Я неграмотен с Kotlin

Вместо использования позиции вы можете попробовать использовать spanIndex

@Override
public void getItemOffsets(final Rect outRect, final View view, final RecyclerView parent, final State state) {
    ... 
    if(isTypeAItemLayout) {
        int column = ((GridLayoutManager.LayoutParams) view.getLayoutParams()).getSpanIndex();
        if (column == 0) {
            // First Column
        } else {
            // Second Column
        }
    }
}
...