Как изменить направление в GridLayoutManager каждой четной линии? - PullRequest
2 голосов
/ 24 февраля 2020

У меня есть layoutManager = GridLayoutManager(context, 3)

Как сделать так, чтобы каждая нечетная линия указывала направление слева направо, а четная - справа налево

Похоже:

0 -> 1 -> 2

5 <- 4 <- 3

6 -> 7 -> 8

etc...

Какие есть идеи, ребята?

Ответы [ 2 ]

1 голос
/ 26 февраля 2020

ОТКАЗ ОТ ОТВЕТСТВЕННОСТИ: у меня телефон, так что это не проверено

Если вы напишите свой RecyclerView.Adapter, вы можете переопределить метод привязки для поиска данных "в неправильном порядке ":

Pos0: данные0 -> Pos1: данные 1 -> Pos2: данные 2
Pos3: данные 5 -> Pos4: данные 4 -> Pos5: данные 3
Pos6: данные 6 -> Pos7: данные 7 -> Pos8: данные 8
Pos9: spacer -> Pos10: spacer -> Pos11: Данные 9

Я предполагаю, что вы передаете некоторую коллекцию данных на ваш адаптер; нам также нужно количество столбцов:

class SnakingAdapter(
    private val data: SomeCollection<SomeObject>, 
    private val cols: Int
) : RecyclerView.Adapter<SomeViewHolder> { ... }

Сначала давайте обработаем крайний случай, когда ваш RecyclerView заканчивается на неполной четной строке. Например, если у вас есть 10 элементов данных (максимальный индекс 9), я предполагаю, что вам нужен последний элемент справа (не слева). Мы сделаем это, создав перед ним 2 элемента «распорки»:

private val twoRows = cols * 2 // left > right & right > left
private val remainder = data.count() % twoRows

// If last row is an odd row => no "spacers"
// If last row is complete => no "spacers"
private val needSpacers = remainder > cols
private val paddedCount = 
    if(needSpacers) (data.count() / twoRows + 1) * twoRows
    else data.count()
private val firstSpacerPosition = data.count() / cols * cols
private val spacerPositions = 
    if(needSpacers) List(paddedCount - data.count()) {  firstSpacerPosition + it }
    else emptyList<Int>()

override fun getItemCount(): Int = paddedCount

override fun getItemViewType(position: Int): Int =
    if(spacerPositions.contains(position)) 2
    else 1

override onCreateViewHolder(parent: ViewGroup, viewType: Int) = when(viewType) { 
    1 => // create a normal item view & ViewHolder
    2 => // create a "spacer" item view & ViewHolder
}

Далее нам нужно связать «неправильные» данные для четных строк:

override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position Int) { 
    // If spacer, do nothing
    if(spacerPositions.contains(position)) return

    // If even row, flip the order of the data
    val twoRowPos = position % twoRows
    val rowTwomidpoint = cols / 2 + cols // TODO: extract as a field
    val altPosition = 
      if (twoRowPos >= cols) (position - 2 * (twoRowPos - rowTwoMidpoint)) // TODO: correct for odd cols; should fix for even cols
      else position

    val data = dataSource.get(altPosition)
    // bind data to view holder here
}
0 голосов
/ 25 февраля 2020

Если вы ищете макет справа налево, попробуйте этот.

Вы пытались выполнить свой код с android:layoutDirection="rtl" на уровне API 17?

...