【Android】Jetpack Compose 入門講座 第15回「リストのスクロール ②LazyRow」
はじめに
前回は Row コンポーネント内のデータをスクロールできるようにしましたが、表示するデータが多い場合に同じ書き方をすると動作が遅くなる原因になります。
これを解消するために LazyRow コンポーネントを使ったコードに書き換えてみましょう。
LazyRowコンポーネント
なぜ LazyRow を使う?
Row コンポーネントを使うと画面に表示されていない画像もあらかじめ用意されている状態です。ですのでデータ数が多くなるとアプリの動作に影響がでる可能性があります。
これを解決できるのが LazyRow コンポーネントです。
LazyRow コンポーネントは必要な分だけ、つまりアプリ画面に表示される画像だけをその都度用意してくれます。
たくさんデータがあってもメモリに負担をかけずにデータを表示することができます。
他にも縦並びにする LazyColumn、グリッド表示する LazyVerticalGrid / LazyHorizontalGrid コンポーネントもあります。
LazyRow に書き換える
基本的な使い方は LazyRow で囲んで、アイテムごとに item 関数を追加していきます。
LazyRow {
item {
Text("Dog")
}
item {
Text("Cat")
}
...
}
しかし LazyRow や LazyColumn はデータが多くなるときに役立つものなので、1つずつアイテムを追加していくのは効率的ではありません。
ここでは画像とテキストの List を用意してアイテムを追加していきます。
AnimalListRow 関数の上に List を追加します(1〜8行目)。
private data class Animal(val drawable: Int, val text: String)
private val animalList = listOf(
Animal(R.drawable.dog, "Dog"),
Animal(R.drawable.cat, "Cat"),
Animal(R.drawable.rabbit, "Rabbit"),
Animal(R.drawable.lion, "Lion"),
Animal(R.drawable.panda, "Panda"),
)
@Composable
fun AnimalListRow(modifier: Modifier = Modifier) {
AnimalListRow 関数のコードを変更します。
@Composable
fun AnimalListRow(modifier: Modifier = Modifier) {
LazyRow {
items(animalList) {
AnimalListElement(drawable = it.drawable, text = it.text)
}
}
}
items 関数で animalList から1つずつデータを取り出してセットしています。
LazyRow コンポーネントは自動的にスクロールを設定してくれるのでコードを追加する必要はありません。
動作確認
プレビューの Interactive Mode を使って動作を確認してみてください。
次に行うこと
次回は画像をグリッド表示するレイアウトを作ってみましょう。
ここまでのコード
package com.example.myapplication
import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.activity.enableEdgeToEdge
import androidx.annotation.DrawableRes
import androidx.compose.foundation.Image
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.statusBarsPadding
import androidx.compose.foundation.lazy.LazyRow
import androidx.compose.foundation.lazy.items
import androidx.compose.foundation.shape.CircleShape
import androidx.compose.material3.Surface
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import com.example.myapplication.ui.theme.MyApplicationTheme
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
enableEdgeToEdge()
setContent {
MyApp()
}
}
}
@Composable
fun MyApp(modifier: Modifier = Modifier) {
MyApplicationTheme {
Surface(
modifier = modifier
.fillMaxSize()
.statusBarsPadding()
) {
AnimalListRow()
}
}
}
@Composable
fun AnimalListElement(
@DrawableRes drawable: Int,
text: String,
modifier: Modifier = Modifier
) {
Column(
horizontalAlignment = Alignment.CenterHorizontally,
modifier = modifier.padding(8.dp)
) {
Image(
painter = painterResource(id = drawable),
contentDescription = text,
contentScale = ContentScale.Crop,
modifier = modifier
.size(80.dp)
.clip(CircleShape)
)
Text(
text = text,
modifier = modifier.padding(top = 4.dp)
)
}
}
private data class Animal(val drawable: Int, val text: String)
private val animalList = listOf(
Animal(R.drawable.dog, "Dog"),
Animal(R.drawable.cat, "Cat"),
Animal(R.drawable.rabbit, "Rabbit"),
Animal(R.drawable.lion, "Lion"),
Animal(R.drawable.panda, "Panda"),
)
@Composable
fun AnimalListRow(modifier: Modifier = Modifier) {
LazyRow {
items(animalList) {
AnimalListElement(drawable = it.drawable, text = it.text)
}
}
}
@Preview
@Composable
private fun AnimalListElementPreview() {
AnimalListElement(drawable = R.drawable.dog, text = "Dog")
}
@Preview
@Composable
private fun AnimalListRowPreview() {
AnimalListRow()
}
@Preview
@Composable
private fun MyAppPreview() {
MyApp()
}