LazyList における offset とは
JetpackCompose の LazyList
において、LazyListState
から様々な情報が取得できます。
そのうち、以下のようにすると各アイテムの offset
という値が取得できます。
val lazyListState = rememberLazyListState()
lazyListState.layoutInfo.visibleItemsInfo.map { it.offset }
この値の説明は以下のようになっています。
The main axis offset of the item in pixels. It is relative to the start of the lazy list container.
すなわち、親となる LazyList
の start 位置からの相対位置を表しています。
例えば、図 1 は実装例を示します。
このとき、「Item 1」の offset
は「Item 0」の高さと一致します。
図 1
これを用いたりして頑張ることで Scrollbar の自前実装ができます。
しかし、LazyList
の設定値次第では一見不思議な値を取るため、二点紹介します。
contentPadding
offset と contentPadding
は LazyColumn
や LazyRow
の引数の一つで、リスト全体に対する padding を指定できます。
図 2 は contentPadding
に PaddingValues(vertical = 40.dp)
を指定した際の例を示します。
@Composable
fun LazyColumn(
...
contentPadding: PaddingValues = PaddingValues(0.dp),
...
): Unit
図 2: contentPadding = PaddingValues(vertical = 40.dp) を指定した場合
図 1 と図 2 における各アイテムの offset
を以下に示します。
図 | (Item 0).offset (px) | (Item 1).offset (px) |
---|---|---|
1 | 0 | 163 |
2 | 0 | 163 |
2 (スクロールした場合) | -105 | 58 |
ここで、(Item 0).size
は 163px で、40dp は 105px でした。
図 1 と図 2 で数値に変化が見られませんが、contentPadding
は offset
に影響しない、というわけではありません。
行「2 (スクロールした場合)」は図 2 を図 1 と見た目が同じになるところまでスクロールした場合の各アイテムの offset
を示しています。
これを見ると、Item 0, Item 1 ともに 40dp (105px) 分減少しています。
この結果から、図 2 では offset
は親の上端を基準とし、contentPadding
を各アイテムに適用したときの上端の位置を表している、と言えそうです。
上記から明らかですが、offset
には contentPadding
のうち top
のみが作用します。
reverseLayout
offset と reverseLayout
は LazyColumn
や LazyRow
の引数の一つで、true
を指定するとレイアウトやスクロール方向を逆転させます。
図 3 は reverseLayout
を true
とした際の例を示します。
@Composable
fun LazyColumn(
...
reverseLayout: Boolean = false,
...
): Unit
図 3: reverseLayout = true を指定した場合
図 1 と図 3 における各アイテムの offset
を以下に示します。
図 | (Item 0).offset (px) | (Item 1).offset (px) |
---|---|---|
1 | 0 | 163 |
3 | 0 | 163 |
ここで、(Item 0).size
は 163px でした。
またもや数値に変化が見られませんが、今回も reverseLayout
は offset
に影響しない、というわけではありません。
ここで図 3 において Item 0 が隠れるようにスクロールをすると、各アイテムの offset
は減少します。
つまり、図 1 では「親の上端」を基準としたときの「各アイテムの上端の位置」を表しているのに対し、図 3 では「親の下端」を基準としたときの「各アイテムの下端の位置」を表していると言えそうです。
なお、ここで更に contentPadding
を指定することもできます。
このとき offset
は「各アイテムの下端の位置」を表しているので、contentPadding
のうち bottom
のみが作用します。
Discussion