Kotlin で Jetpack Compose, Retrofit を使って API リクエスト、JSON パース して、グリッド表示するコードをファイル別に表示して

Kotlin で Jetpack Compose と Retrofit を使って API リクエスト、JSON パースして、グリッド表示するためには、以下のようにファイルを分けることができます。

 

1. API リクエストを行うための Retrofit インターフェースを定義するファイル


interface ApiService {

    @GET("/photos")
    suspend fun getPhotos(): List<Photo>
}

 

2. API レスポンスを表すデータクラスを定義するファイル


data class Photo(
    val id: Int,
    val title: String,
    val url: String
)

 

3. API レスポンスをパースして、表示するための画面を定義するファイル


@Composable
fun PhotoGrid() {
    val photos by remember { mutableStateOf<List<Photo>>(emptyList()) }

    LaunchedEffect(Unit) {
        val apiService = Retrofit.Builder()
            .baseUrl("https://jsonplaceholder.typicode.com")
            .addConverterFactory(Json {
                ignoreUnknownKeys = true
            }.asConverterFactory("application/json".toMediaType()))
            .build()
            .create(ApiService::class.java)

        photos = apiService.getPhotos()
    }

    LazyVerticalGrid(cells = GridCells.Adaptive(minSize = 128.dp)) {
        items(photos) { photo ->
            Card(
                modifier = Modifier.padding(4.dp),
                shape = RoundedCornerShape(8.dp),
                elevation = 4.dp
            ) {
                Column(
                    Modifier
                        .fillMaxWidth()
                        .height(128.dp)
                        .padding(8.dp)
                ) {
                    Text(
                        text = photo.title,
                        style = MaterialTheme.typography.subtitle1,
                        maxLines = 2,
                        overflow = TextOverflow.Ellipsis
                    )
                    Spacer(modifier = Modifier.weight(1f))
                    CoilImage(
                        data = photo.url,
                        contentScale = ContentScale.Crop,
                        modifier = Modifier.fillMaxSize()
                    )
                }
            }
        }
    }
}

 

4. 上記の画面を表示するための Activity もしくは Fragment を定義するファイル


class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            PhotoGrid()
        }
    }
}

以上のように、ファイルを分けることで、API リクエストやパース、表示を分離し、コードを見やすく、メンテナンスしやすくすることができます。

 

■ 感想

ただ、一行問いかけただけ。

ChatGPT で、ここまで書けるとは。



【Android】Version Catalog + JetpackCompose UI + BOM

Compose の BOM。

【Android】Version Catalog + JetpackCompose UI + BOM
👉 Google's Maven Repository hatena-bookmark

公開されているので使ってみます。

少し公式ドキュメントで調べておきます。

BOM の使用は義務ですか?

いいえ。個々の依存関係バージョンを手動で追加することもできます。しかし、すべての最新の安定版を同時に使用することが容易になるので、BOM を使用することをおすすめします。

Compose Compiler ライブラリが BOM に含まれていないのはなぜですか?

Compose Kotlin コンパイラ拡張機能(androidx.compose.compiler)は、Compose ライブラリのバージョンでなく、Kotlin コンパイラ プラグインのバージョンにリンクされており、Compose の他の部分とは異なる頻度でリリースされます。したがって、お使いの Kotlin バージョンと互換性のあるバージョンを使用してください。

👉 Using the Bill of Materials  |  Jetpack Compose  |  Android Developers hatena-bookmark

公式サンプルコードを少し変更したものを準備しておきます。


# libs.versions.toml

[libraries]
compose-ui-bom = { module = "androidx.compose:compose-bom", version = "2023.01.00" }


// build.gradle

dependencies {
  implementation platform(libs.compose.ui.bom)
}

👉 BOM to library version mapping  |  Jetpack Compose  |  Android Developers hatena-bookmark

 

■ 実装

実装としては、以下でいけました。


# libs.versions.toml

[libraries]

compose-ui-bom = { module = "androidx.compose:compose-bom", version = "2023.01.00"}
compose-material = { module = "androidx.compose.material:material" }
compose-material-icons = { module = "androidx.compose.material:material-icons-extended" }
compose-ui = { module = "androidx.compose.ui:ui" }
compose-ui-tooling-preview = { module = "androidx.compose.ui:ui-tooling-preview" }


// build.gradle

dependencies {

  // compose-ui
  implementation platform(libs.compose.ui.bom)
  implementation libs.compose.material
  implementation libs.compose.material.icons
  implementation libs.compose.ui
  implementation libs.compose.ui.tooling.preview

}

 

■ まとめ

BOM を使っていなかったのですが、エラーが出始めたので、使うことにしました。

「整合性の適正化」と「グループ化」の機能を持っている「BOM」は、Kotlin, Firebase などでも公開されています。

便利に利用するべきでしょう。

しかし、AndroidStudio のコレ。

JetpackCompose UI で BOM

「null」 の表示。

どうにかなりませんかね。

👉 今はまだ必要な Android ライブラリ の Bill of Materials(BOM) のURLs hatena-bookmark


【Git】.gitignore の状態を確認するコマンドたち

git status --ignored

まずは、状態の確認をしましょう。

以下は、基本的な Android プロジェクトでの例。


 

■ 位置を確認する


❯ find . -name .gitignore                          
./app/.gitignore
./.gitignore
./.idea/.gitignore

👉 AndroidStudio 新規プロジェクトテンプレートから考える .gitignore hatena-bookmark

 

■ git status


❯ git status          
On branch main
Your branch is up to date with 'origin/main'.

nothing to commit, working tree clean

 

■ git status --ignored


❯ git status --ignored
On branch main
Your branch is up to date with 'origin/main'.

Ignored files:
  (use "git add -f <file>..." to include in what will be committed)
        .gradle/
        .idea/workspace.xml
        app/build/
        local.properties

nothing to commit, working tree clean

→ ignore 対象が確認できます。

 

■ git clean -ndX


❯ git clean -ndX
Would remove .gradle/
Would remove .idea/workspace.xml
Would remove app/build/
Would remove build/
Would remove local.properties

 

■ git check-ignore -v


❯ git check-ignore -v .gradle/           
.gitignore:2:.gradle    .gradle/

❯ git check-ignore -v .idea/workspace.xml
.idea/.gitignore:3:/workspace.xml       .idea/workspace.xml

❯ git check-ignore -v app/build/         
app/.gitignore:1:/build app/build/

❯ git check-ignore -v local.properties
.gitignore:15:local.properties  local.properties

❯ git check-ignore -v **/*
app/.gitignore:1:/build app/build
app/.gitignore:1:/build app/build/generated
app/.gitignore:1:/build app/build/generated/ap_generated_sources
app/.gitignore:1:/build app/build/generated/ap_generated_sources/debug
app/.gitignore:1:/build app/build/generated/ap_generated_sources/debug/out
app/.gitignore:1:/build app/build/generated/res
...

→ そのファイルを ignore するパターン記述を特定することができます。

 

■ git ls-files --other --ignored --exclude-standard


❯ git ls-files --other --ignored --exclude-standard
.gradle/7.5.1/checksums/checksums.lock
.gradle/7.5.1/dependencies-accessors/dependencies-accessors.lock
.gradle/7.5.1/dependencies-accessors/gc.properties
.gradle/7.5.1/executionHistory/executionHistory.bin
.gradle/7.5.1/executionHistory/executionHistory.lock
...

→ 実際に ignore されたファイル一覧が確認できます。Adroid プロジェクトでは出力行が多くなるので省略しています。

 

■ 参考

👉 Git のステータス: リポジトリの検査 | Atlassian Git Tutorial hatena-bookmark


AndroidStudio 新規プロジェクトテンプレートから考える .gitignore

標準的な Android アプリ開発環境である AndroidStudio デフォルトのテンプレートは王道。

そのタイミングでの標準的なテンプレートです。

 

■ AndroidStudio プロジェクトデフォルト

今現在、公開されているプロジェクトテンプレートから確認してみます。

Empty Activity を選択しました。

AndroidStudio 新規プロジェクトテンプレートから考える .gitignore

👉 benigumocom/EmptyActivity-2023-02-09: androidstudio default template hatena-bookmark

プロジェクトルートから .gitignore を探ります。



これからスタートするのがいいでしょう。

 

■ A collection of .gitignore templates - github/gitignore

A collection of .gitignore templates

This is GitHub’s collection of .gitignore file templates. We use this list to populate the .gitignore template choosers available in the GitHub.com interface when creating new repositories and files.

👉 github/gitignore: A collection of useful .gitignore templates hatena-bookmark

GitHub 公式のリポジトリから公開されています。

Android アプリ開発に必要そうなものを挙げていきます。


👉 gitignore/JetBrains.gitignore at main · github/gitignore hatena-bookmark


👉 gitignore/macOS.gitignore at main · github/gitignore hatena-bookmark


👉 gitignore/Android.gitignore at main · github/gitignore hatena-bookmark


👉 gitignore/Gradle.gitignore at main · github/gitignore hatena-bookmark

Kotlin.gitignore は、以下 Java.gitignore のエイリアス。

👉 gitignore/Java.gitignore at main · github/gitignore hatena-bookmark

 

■ gitignore.io - toptal/gitignore


👉 gitignore.io - Create Useful .gitignore Files For Your Project hatena-bookmark で利用されている .gitignore リソースは以下で公開されています。

👉 gitignore/templates at master · toptal/gitignore hatena-bookmark

基本的には、先に紹介した github/gitignore と同じものですが、こちら側のみで公開している .gitignore があります。

なので、それらを貼っておきます。


👉 AndroidStudio.gitignore hatena-bookmark


👉 gitignore/Groovy.gitignore at master · toptal/gitignore hatena-bookmark


👉 gitignore/Firebase.gitignore at master · toptal/gitignore hatena-bookmark

 

■ まとめ

以上を参考にすれば、ほぼ書けるはずです。

AndroidStudio 新規プロジェクト作成時に書き出される .gitignore が必要最小限な洗練されてる記述に思えます。

あとは、不要なファイル公開を避ける記述を追加していく、という流れ。

git 全体としては、広く深く記述もいろいろなのでよく使うとこから身につけていく方がいいと思います。

👉 【これだけで大丈夫】.gitignore チートシート - A Memorandum hatena-bookmark

.gitignore 概念の説明や操作としては、GitHub 公式 Doc が最も分かりやすくまとまっています。

👉 ファイルを無視する - GitHub Docs hatena-bookmark
👉 What makes a good template? - github/gitignore: A collection of useful .gitignore templates hatena-bookmark


プログラミング でも UI でも 等幅フォント「Martian Mono」はいい感じ。

Martian Monoは、Martian Grotesk(myfonts.com)の等幅バージョンで、Groteskのすべての利点を継承しつつ、コード用とデザイン用に制作されたフォントです。

ライセンスはSIL Open Font License 1.1で、商用プロジェクトでも無料で使用できます。

👉 プログラミング用フォントとUIデザインのどちらにも使える! 美しさと読みやすさを兼ね備えたフォント「Martian Mono」 | コリス hatena-bookmark

良さげなので、IDEA/AndroidStudio に適用してみましたが、エディター内コードのテキスト、IDE の UI のテキスト、両方共にすごくいいです!

プログラミング でも UI でも フォント「Martian Mono」はいい感じ。

プログラミング でも UI でも フォント「Martian Mono」はいい感じ。

きれいでくっきりと分かりやすいフォントです。

私の場合はあまり目が良くないので、すべてのテキストサイズは 14 に統一しています。

プログラミング でも UI でも フォント「Martian Mono」はいい感じ。

プログラミング でも UI でも フォント「Martian Mono」はいい感じ。

プログラミング でも UI でも フォント「Martian Mono」はいい感じ。

プログラミング でも UI でも フォント「Martian Mono」はいい感じ。

プログラミング でも UI でも フォント「Martian Mono」はいい感じ。

プログラミング でも UI でも フォント「Martian Mono」はいい感じ。

多少、目が悪くても、光の当たり方が悪くても、すごく見やすくて分かりやすいです。

おすすめです。

ちなみに、上の画像は、最も標準的な Std Rg otf を入れたものです。

👉 evilmartians/mono: Free and open-source monospaced font from Evil Martians hatena-bookmark