5
1

More than 1 year has passed since last update.

PokéAPI を使ってポケモン図鑑の Android を作ってみた

Last updated at Posted at 2021-12-08

この記事は,フラー株式会社 Advent Calendar 2021 の 9 日目の記事です。

8 日目の記事は @inoriko711 さんによる きらめく星(の力で憧れの私)描くよ でした。

はじめに

僕は フラー株式会社 で Android エンジニアのアルバイトのオンボーディング(研修)期間中に PokéAPI を使ったポケモン図鑑アプリ作りました。これ がそのアプリです。恥ずかしいからみないでください。MVVM とかあまりよくわからないまま適当に作ったと思います。

もう,バイトを始めて 8 ヶ月くらい経ちました1。色々なライブラリや MVVM とは何か,Jetpack Compose... などの色々なことを触れることができたので,改めて簡単なポケモン図鑑 Android アプリを作ります。今回は Jetpack Compose による Android MVVM アーキテクチャ入門 を全面的にパクリって参考にして Compose を使ったポケモン図鑑を作成します2。ちゃんと説明するのがめんどくさいので参考書や これ(今回書いたコード) を見てください。

PokéAPI とは

PokéAPI はポケモンに関する大量のデータ(ポケモン,技,タイプ,特性,ゲームバージョン,図鑑説明,アイテムなど)があります。詳しくは PokéAPI/About を確認してください。

例えば https://pokeapi.co/api/v2/pokemon/ditto/ のように API を叩くと,メタモンに関するデータが取得できます。API の叩き方や取得できるデータについては PokéAPI/Doc を確認してください。とっても詳しく書いてあります。

仕様を決める

ポケモン図鑑(リスト) ポケモン詳細
Screenshot_20211207-175546.png Screenshot_20211207-175550.png

↑のように,番号順でポケモンが並んでいて,ポケモンをタップすることで,そのポケモンの詳細画面を表示しようと思います。詳細画面には,

  • 全国図鑑でのポケモンの番号
  • ポケモンの名前(英名)
  • ポケモンの画像(正面から 1 種類だけ)

を表示しようと思います。

タイプや図鑑説明は pokemon-species を別途叩かないといけないので,めんどくさいのでやりません。

いざ作成

基本的な流れは Android MVVM アーキテクチャ入門 の通りに進めていきます。特に変えた点を説明していきます。わからないところは これ を見て気合いで乗り越えてください。

Android Studio の New Project から Empty Comose Activity を選択してプロジェクトを作成してください。

ライブラリ

build.gradle / app/build.gradle には以下のものを追加します。簡単に説明すると OkHttp と Retrofit で API を叩き,Kotlin Serialization で Json をパースします。Coil はポケモンの画像を表示するために使います。ViewModel は ViewModel 用で(あたりまえ体操)Compose で UI の実装をします。Hilt は DI ライブラリです。

build.gradle
buildscript {
    ...
    dependencies {
        ...
        classpath "org.jetbrains.kotlin:kotlin-serialization:1.5.31"
        classpath "com.google.dagger:hilt-android-gradle-plugin:2.37"
    }
}
app/build.gradle
dependencies {
    ...
    implementation "androidx.lifecycle:lifecycle-viewmodel-compose:2.4.0"
    implementation "com.squareup.okhttp3:okhttp:4.9.2"
    implementation "com.squareup.retrofit2:retrofit:2.9.0"
    implementation "org.jetbrains.kotlinx:kotlinx-serialization-json:1.2.2"
    implementation "com.jakewharton.retrofit:retrofit2-kotlinx-serialization-converter:0.8.0"
    implementation "com.google.dagger:hilt-android:2.39.1"
    implementation "io.coil-kt:coil-compose:1.4.0"
    kapt "com.google.dagger:hilt-compiler:2.39.1"
}

API

PokéAPI を叩きましょう。全国図鑑のリストを返す pokedex/national とポケモンの情報を取得する pokemon/{name} が叩けるようにします。{name} でわかると思いますが,getPokeApiPokemon はポケモンの名前または番号を引数とします。それぞれ PokeApiPokedexPokeApiPokemon を戻り値とします。

PoroviderModule 及び RemoteDataSource... の説明は書略します。

ApiClient
interface ApiClient {
    @GET("pokedex/national")
    suspend fun getPokeApiPokedex(): Response<PokeApiPokedex>

    @GET("pokemon/{name}")
    suspend fun getPokeApiPokemon(@Path("name") name: String): Response<PokeApiPokemon>
}

data class

ポケモン図鑑(リスト)用と,ポケモンの詳細用のデータクラスを作成します。Retrofit の依存関係を含んだ API 側と,依存関係を含まないデータクラスを両方作成します。

ここではめんどくさいので Pokemon の説明だけをします。

まず API からの情報のうち,id, name, sprites を取得します。sprites はポケモンの画像色々な画像の URL です。取得したデータを使うときは,一度依存関係のない Pokemon にデータを変換して使います。

PokeApiPokemon
@Serializable
data class PokeApiPokemon(
    @SerialName("id") val id: Int,
    @SerialName("name") val name: String,
    @SerialName("sprites") val sprites: PokeApiSprites,
)

@Serializable
data class PokeApiSprites(
    @SerialName("back_default") val back_default: String,
    @SerialName("front_default") val front_default: String,
)
Pokemon
data class Pokemon(
    val id: Int,
    val name: String,
    val frontImage: NetworkImage,
)

Repository

そんなに参考書と変えてないので省略です。

UI

ポケモン図鑑の情報を取得するために,MainViewModel に次のコードを書きます。

MainViewModel
fun getPokedex() {
        viewModelScope.launch {
            uiState.value = UiState.Loading
            runCatching {
                pokemonRepository.getPokedex()
            }.onSuccess {
                uiState.value = UiState.SuccessPokedex(pokedex = it)
            }.onFailure {
                uiState.value = UiState.Failure
            }
        }
    }

ポケモン図鑑(リスト)が表示される PokedexView と,ポケモンの詳細が表示される PokemonDetailView を作ります。

PokedexView は全てのポケモンを並べて表示するので,LazyColumn を使います。Text は番号と名前を適当にくっつけたものとして,タップすると onPokemonTapped を呼び出し ViewModel に伝えます。ViewModel ではポケモンの情報を取得します。

PokedexView
@Composable
fun PokedexView(pokedex: Pokedex, onPokemonTapped: (name: String) -> Unit) {
    LazyColumn {
        pokedex.pokemonEntries.forEach { pokemonEntry ->
            item {
                Text(
                    text = "No. " + pokemonEntry.entryNumber.toString() +
                            ": " + pokemonEntry.pokemonSpecies.name,
                    modifier = Modifier
                        .height(30.dp)
                        .clickable { onPokemonTapped(pokemonEntry.entryNumber.toString()) },
                )
            }
        }
    }
}

PokemonDetailView では idname の他にポケモンの正面の画像を表示します。painter = rememberImagePainter(URL) で URL にある画像を簡単に表示しています。BackHandler で戻るボタンが押されたときに backHome() します。実際には getPokedex() を呼び出しています。

PokemonDetailView
@Composable
fun PokemonDetailView(pokemon: Pokemon, backHome: () -> Unit) {
    Column {
        Text(
            text = "No. " + pokemon.id.toString()
        )
        Text(
            text = pokemon.name.replaceFirstChar {
                if (it.isLowerCase()) it.titlecase(Locale.getDefault()) else it.toString()
            }
        )
        Image(
            painter = rememberImagePainter(pokemon.frontImage.url.value),
            contentDescription = null,
            modifier = Modifier.size(128.dp)
        )
    }
    BackHandler(enabled = true) {
        backHome()
    }
}

最後に

Compose はすごく便利です。ポケモン図鑑表示みたいに複数のものを並べるのも簡単ですし,データへのアクセスも XML を使うときより簡単に感じます。

時間の関係で結構適当なアプリ / 記事になってしまい残念です。アプリ修正して,丁寧な説明を追加して個人ブログに載せたいな〜と思ってます。めんどくさいからやらない気がするけど...

文献

  1. 作成したソースコード (GitHub)
  2. PokéAPI
  3. Jetpack Compose による Android MVVM アーキテクチャ入門
  4. zsoltk/compose-pokedex (GitHub)

  1. 週に 2 日くらいです。合計 300 時間くらいですね。 

  2. 完成度が高い Compose を使ったポケモン図鑑をみたい人は,zsoltk/compose-pokedex (GitHub) が参考になると思います。 

5
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
1