5
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

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

5
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

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?