
みなさまこんにちは〜!
メモリアインクのすだです。
本日は、
KotlinのJetpack Composeを使ったリスト表示のUI実装について
実際のコードを利用して徹底解説していきます!
この記事を読んでわかること…
・Jetpack ComposeのLazyColumnとは?
・Jetpack ComposeのLazyColumnを使ったリスト表示の実装方法
環境
- Kotlin (ver 1.9.0)
- Android Studio (Giraffe | 2022.3.1 Patch 3)
LazyColumnとは?
LazyColumnは、Jetpack Composeで提供されている、縦方向のリスト表示用コンポーネントです。
従来の RecyclerView と似たアプローチで、
「表示されていないアイテムは描画しない」ことで、パフォーマンスを最適化しています。
スクロール可能かつ高パフォーマンスでUIを構築できます。
LazyColumnの基本的な使い方
LazyColumn {
items(5) { index ->
Text(text = "Item #$index")
}
}
items(5)
は、「0 から 5 までの合計10個の要素を表示する」指定です。index
には現在の項目番号(0〜5)が渡されます。
これにより表示されるリストのイメージは以下です:
Item #1
Item #2
Item #3
Item #4
Item #5
これをたとえば、items(リスト)
とすれば、リストや配列などのデータを使って表示も可能です:
val names = listOf("Taro", "Hanako", "Jiro")
LazyColumn {
items(names) { name ->
Text(text = "Name: $name")
}
}
さらに応用して、リスト項目のテキストサイズや余白などを変更することもできます:
@Composable
fun NameList(names: List<String>) {
LazyColumn(modifier = Modifier.fillMaxSize()) {
items(names) { name ->
Text(
text = name,
fontSize = 20.sp,
modifier = Modifier
.padding(12.dp)
.fillMaxWidth()
)
}
}
}
// 呼び出し例
@Composable
fun MainScreen() {
val sampleNames = listOf("山田太郎", "佐藤花子", "高橋次郎")
NameList(names = sampleNames)
}
実践的な実装
スクロール制御と位置取得
スクロール位置を制御したい場合は、rememberLazyListState()
を使います。
たとえば、「トップへ戻る」ボタンをタップすると、リストの先頭へスクロールという挙動を実装してみます。
@Composable
fun ScrollExample() {
val listState = rememberLazyListState()
Column {
Button(onClick = {
// 先頭にスクロール
CoroutineScope(Dispatchers.Main).launch {
listState.animateScrollToItem(0)
}
}) {
Text("トップへ戻る")
}
LazyColumn(
modifier = Modifier.fillMaxSize(),
state = listState
) {
items(names) { name ->
Text(
text = name,
fontSize = 20.sp,
modifier = Modifier
.padding(12.dp)
.fillMaxWidth()
)
}
}
}
}
val listState = rememberLazyListState()
rememberLazyListState()
は、リストのスクロール状態(どこまでスクロールされているか)を保持するオブジェクトです。
この listState
を LazyColumn(state = listState)
に渡すことで、リストの状態を制御・取得できるようになります。
Column { … }
Column
は、縦方向にUIを並べるためのレイアウトコンポーネントです。この中に「ボタン」と「リスト」を順番に配置します。
CoroutineScope(Dispatchers.Main).launch { … }
非同期でスクロールを行うべく、CoroutineScopeを使用します。animateScrollToItem()
は、スクロール位置を滑らかに動かすアニメーション付きのスクロール処理です。つまり、「UIスレッド上で、非ブロッキングにスクロールさせたい」という意図があります。
コルーチンを使う背景:animateScrollToItem()
は suspend
修飾子がついた関数(=中断可能関数) です。
suspend fun LazyListState.animateScrollToItem(...)
これにより、この関数はコルーチン内でしか呼び出せないという制約があります。
スクロールには一定の時間がかかる処理(アニメーション)なので、
呼び出し元をブロックしないようにするために suspend で定義されています。
(Jetpack Compose の UIは “メインスレッドを止めずに動かす” のが大前提)
animateScrollToItem(0)
で、リストの先頭(インデックス0のアイテム)へスムーズにスクロールします。
LazyColumn(state = listState)
state = listState
によって、このリストのスクロール位置を外部(ボタン側)から制御できるようになります。
リスト項目の間に余白・区切り線を入れる
@Composable
fun ListWithDividerAndSpacing() {
LazyColumn(
verticalArrangement = Arrangement.spacedBy(12.dp), // 各アイテム間のスペース
contentPadding = PaddingValues(16.dp) // リスト全体の余白
) {
items(20) { i ->
Column(
modifier = Modifier
.fillMaxWidth()
) {
Text(
text = "Item $i",
modifier = Modifier
.padding(12.dp)
.fillMaxWidth()
)
Divider(
color = Color.LightGray,
thickness = 1.dp,
)
}
}
}
}
verticalArrangement = Arrangement.spacedBy(12.dp)
これでリスト項目同士の外側の間隔を均等にします。
そしてcontentPadding = PaddingValues(16.dp)
でリストの上下左右に全体的な余白を追加します。
Column
の中に Text
+ Divider
をセットすることで、それぞれのアイテムの下に区切り線を表示することができます。Divider
の中には、区切り線の詳細を書いてあげてください。
まとめ
おつかれさまでした。いかがでしたでしょうか!
Jetpack Compose でリストを表示するには、LazyColumn
を使うのが基本です。
リスト項目に余白を追加したり、区切り線(Divider)を入れることで、視認性の高いリッチなUIを実現できます。



技術者としてのキャリアパスを次のレベルへと進めたい皆様、
未経験からIT・Webエンジニアを目指すなら【ユニゾンキャリア】
自分の市場価値をさらに向上させてみませんか?
それではまた次の記事でお会いしましょう!
コメント