Compose LazyColumn:Columnとの違い

投稿日:  更新日:

LazyColumnとColumnはどちらも一覧(リスト)表示するUIです。

記述方法は違いますが、スクロールしたり、アイテムを制御したり、ほぼ同じことが出来ます。

ただし、両者の特徴により、向き不向きがあります。よく違いを理解して、適材適所で使い分けが必要です。

ここでは、両者の違いをまとめました。

※環境:Android Studio Koala | 2024.1.1
    Kotlin 1.9.0
    Compose Compiler 1.5.1
    androidx.compose.foundation:foundation 1.6.8

スポンサーリンク

Columnとの違い

LazyColumnは、「複数のデータやオブジェクト」または「コレクション」を、一覧表示するUIです。

同様なことがColumnでも出来ます。しかし、表に示すような特徴があります。

評価項目ColumnLazyColumn
(1)記述の容易さ
(2)パフォーマンス小規模リスト(表示範囲+α程度)
大規模リスト
×
(3)アイテムの制御 ※制御:変更、追加、削除、移動
※◎:とても適する、○:適する、△:あまり適しない、×:適しない

適材適所で使い分けが必要です。

スポンサーリンク

記述の容易さ

LazyColumnはDSLを用いてアイテムの並びを記述します。ですので、DSLの理解が必要です。
※各DSLの詳細は「Compose LazyColumn:LazyListScope DSL」を参照

サンプルのコレクションデータ
@Stable
data class PlayerInfo(
    val id: Int,
    val name: String,
    var level: Int = 1,
    var score: Int = 0
)

val playerList = listOf(
    PlayerInfo(1, "Taro", 10, 3060),
    PlayerInfo(2, "Jiro", 2, 1237),
    PlayerInfo(3, "Miki", 15, 3469),
    PlayerInfo(4, "Miku", 22, 3999),
    PlayerInfo(5, "Goro", 3, 460),
    PlayerInfo(6, "Yuri", 8, 567),
    PlayerInfo(7, "Riku", 11, 2870),
    PlayerInfo(8, "Mami", 10, 1260),
    PlayerInfo(9, "Mako", 24, 4309),
    PlayerInfo(10, "Ken", 5, 132),
    PlayerInfo(11, "Ryo", 9, 999),
    PlayerInfo(12, "Naoto", 9, 3497),
    PlayerInfo(13, "Ryoko", 17, 4000),
    PlayerInfo(14, "Satosi", 18, 4001),
    PlayerInfo(15, "Nanako", 1, 123),
    PlayerInfo(16, "Natuki", 25, 903),
    PlayerInfo(17, "ai", 29, 5500),
    PlayerInfo(18, "Rin", 1, 12),
    PlayerInfo(19, "Jun", 14, 2390),
    PlayerInfo(20, "Hana", 10, 2200)
)
    Column(
        modifier = Modifier
            .fillMaxSize()
            .verticalScroll(rememberScrollState()),
        verticalArrangement = Arrangement.spacedBy(2.dp),
    ) {
        headerItem()
        playerList.forEach {
            playerItem(it.name, it.level, it.score)
        }
    }
    LazyColumn(
        modifier = Modifier.fillMaxSize(),
        verticalArrangement = Arrangement.spacedBy(2.dp)
    ) {
        @OptIn(ExperimentalFoundationApi::class)
        stickyHeader {					// DSLコマンド
            headerItem()
        }
        items(playerList) { item ->		// DSLコマンド
            playerItem(item.name, item.level, item.score)
        }
    }

両者は同じ表示になります。スクロールも可能です。

LazyColumnのサンプル

スポンサーリンク

パフォーマンス

小規模リストはColumn、大規模リストはLazyColumnが適しています。

 Column 

Columnは初回のコンポーズで、すべてのアイテムをComposition内に展開します。これは、1000個のアイテムがあれば1000個のUIが展開される事を意味します。

ですので、アイテムが多くなればなるほど、端末のリソース(メモリーやCPU処理能力)をより多く消費し、その影響でパフォーマンスは低下します。

スクロールは、Composition内のアイテム上をウィンドウが移動するイメージです。

ColumnのComposition

 LazyColumn 

LazyColumnは初回のコンポーズで、表示分のアイテムをComposition内に展開します。サンプルは、6個のアイテムが表示可能なので、6個のUIが展開されています。

ですので、アイテムが多くなったとしても、端末のリソースの消費量は一定で、パフォーマンスの低下は起こりません。

スクロールは、スクロール先のUIを事前準備する関係で、Composition内のアイテム数が多少増加しますが、表示可能なアイテム数のx1.8~2.0程度です。その後は、既存のアイテムを使い回し、数は変化しません。

LazyColumnのComposition

スポンサーリンク

アイテムの制御

ColumnもLazyColumnもアイテムの制御(変更/追加/移動/削除)は可能です。また、不要な再Composeを排除するために、アイテムをキーで認識することも可能です。

ただし、LazyColumnのキーはLazyListScope DSL内に組み込まれているので、個別にkey関数を使う必要がありません。

@Stable
data class NumData(val id: Int, var num: Int)

private var ID: Int = 100
private fun newData() = try { NumData(ID, ID) } finally { ID++ }

@Composable
private fun SampleList_a(datas: List<NumData>) {
    val _datas = remember {
        mutableStateListOf<NumData>().apply { addAll(datas) }
    }

    Column {
        _datas.forEach {
            key(it.id) {
                ItemBox { Text(text = "Item %02d (Column)".format(it.num)) }
            }
        }
    }

    Button(
        onClick = { _datas.add(4, newData()) }
    ) { Text(text = "ins")}
}
@Stable
data class NumData(val id: Int, var num: Int)

private var ID: Int = 100
private fun newData() = try { NumData(ID, ID) } finally { ID++ }

@Composable
private fun SampleList_1(datas: List<NumData>) {
    val _datas = remember {
        mutableStateListOf<NumData>().apply { addAll(datas) }
    }

    LazyColumn {
        items(items = _datas, key = { it.id }) {
            ItemBox { Text(text = "Item %02d".format(it.num)) }
        }
    }

    Button(
        onClick = { _datas.add(4, newData()) },
    ) { Text(text = "ins")}
}

※DSLの詳細は「Compose LazyColumn:LazyListScope DSL」を参照
※「アイテムの制御」の詳細は「… LazyColumn:アイテムの制御(Ch…)」を参照

スポンサーリンク

関連記事:

Jetpack composeは、アプリ開発に必要な一通りのUIコンポーネントをライブラリで提供しています。 そのライブラリ中のLazyColumnについて、構成や使用方法などをまとめます。 ※環境:Android Studio Koala | 2024.1.1     Kotlin 1.9.0     Compose Compiler 1.5.1     androidx.compose.foundation:foundation 1.6.8 ...
LazyColumnはLazyListScope DSLコマンドを使ってアイテムの並びを記述します。 コマンドは7つあり、各々について例を示します。 ※環境:Android Studio Koala | 2024.1.1     Kotlin 1.9.0     Compose Compiler 1.5.1     androidx.compose.foundation:foundation 1.6.8 ...
LazyColumnは「複数のデータやオブジェクト」または「コレクション」を一覧(リスト)表示するUIです。 単純に一覧表示できれば良い用途もありますが、表示に加えてアイテムの制御(変更/追加/移動/削除)を必要とする場面が多くあります。 最近の携帯端末はパソコンと同じ利便性をアプリに求めますから、「データの表示だけでなく編集もできる」という機能は必須の要望です。 ここでは、LazyColumnでアイテムの制御を行う方法を紹介します。 ※環境:Android Studio Koala | 2024.1.1     Kotlin 1.9.0     Compose Compiler 1.5.1     androidx.compose.foundation:foundation 1.6.8 ...
ある成果物の開発を進めるに時に、「先に問題へ対応する」と「後で問題へ対応する」では、後者の方が難易度は高いです。 開発は進むにつれて周辺との因果関係が複雑化ます。全体に影響を与えない形で問題へ対応することが、難しくなるからです。 不要な再Composeを回避する対応も同じだと思います。 ですので、発生源が明確で不要な再Composeは、コーディングの段階で潰しておくべきです。 ただし、不要な再Composeの発生源を知らなければ出来ません。 ここで紹介するList型入力は、不要な再Composeの発生源の一つです。 ※環境:Android Studio Koala | 2024.1.1     Kotlin 1.9.0     Compose Compiler 1.5.1     androidx.compose.foundation:foundation 1.6.8     kotlinx.collections.immutable 0.3.7 ...
ある成果物の開発を進めるに時に、「先に問題へ対応する」と「後で問題へ対応する」では、後者の方が難易度は高いです。 開発は進むにつれて周辺との因果関係が複雑化ます。全体に影響を与えない形で問題へ対応することが、難しくなるからです。 不要な再Composeを回避する対応も同じだと思います。 ですので、発生源が明確で不要な再Composeは、コーディングの段階で潰しておくべきです。 ただし、不要な再Composeの発生源を知らなければ出来ません。 ここで紹介するListStateは、不要な再Composeの発生源の一つです。 ※環境:Android Studio Koala | 2024.1.1     Kotlin 1.9.0     Compose Compiler 1.5.1     androidx.compose.foundation:foundation 1.6.8 ...
Jetpack composeは、アプリ開発に必要な一通りのUIコンポーネントをライブラリで提供しています。 そのライブラリ中のLazyRowについて、構成や使用方法などをまとめます。 ※環境:Android Studio Koala | 2024.1.1 Patch 1     Kotlin 1.9.0     Compose Compiler 1.5.1     androidx.compose.foundation:foundation 1.6.8 ...
スポンサーリンク