見出し画像

「COMPOSE を用いた ANDROID アプリ開発の基礎」の学習支援⑭ -ユニット4パスウェイ3

皆さん、こんにちは!又はこんばんは!初めての方は初めまして!
Google Codelabsの「COMPOSE を用いた ANDROID アプリ開発の基礎」コースのお手伝いをする「りおん」です。
今回は、ユニット4「ナビゲーションとアプリアーキテクチャ」のパ
スウェイ3「さまざまな画面サイズに適応する」です。

補足のため、「COMPOSE を用いた ANDROID アプリ開発の基礎」コースで心配になった時、エラーが起きて詰まった時や、分からないことがあった時、軽く復習したい時に見てください!
目次を見て、自分に必要なところだけ見るのをお勧めします!

この記事を作成するにあたり使用しているAndroid StudioのバージョンはGiraffeです。バージョンによってはUIが違うことがあるのでご了承ください。
また、2024年3月20日現在の「COMPOSE を用いた ANDROID アプリ開発の基礎」コースを参考にしています。


学習内容

③ダイナミック ナビゲーションを使用してアダプティブ アプリを作成する

この章で学習した内容は大きく2つです。
1つ目はサイズ変更可能なエミュレータの作成方法
2つ目はWindowSizeClass APIを使用して画面サイズに対応したアプリを作成する方法でした。

エミュレータの作成方法は、通常のエミュレータ作成方法同様に、[Tools] -> [Device Manager] -> [Create device] 、その後[Phone] カテゴリの[Resizable (Experimental)] デバイスを選択します。

サイズ変更可能なエミュレータ

WindowSizeClass APIを使用して画面サイズに対応したアプリを作成する手順は以下の通りです

①material3-window-size-class 依存関係を追加する

②MainActivity.kt ファイルの onCreate() 関数内でcalculateWindowSizeClass メソッドを使用した変数を作成する

今回は、変数windowSizeにウィンドウのサイズを格納している

③ウィンドウサイズクラスの3つのカテゴリ(Compact, Medium, Expanded)それぞれのレイアウトを作成する

今回は、whenを用いて各カテゴリ毎に別のレイアウトとなるようにしている

(④このCodelabsでは、UIナビゲーションとして画面サイズがCompactなものはボトムナビゲーション、Mediumはナビゲーションレール、Expandedは永続 / 固定ナビゲーション ドロワーが推奨されています)

UIナビゲーション

④アダプティブ レイアウトでアプリを作成する

大画面のレイアウトを改良するために、正規レイアウト(の中のリスト詳細ビュー)という大画面を設計する時の基本となるレイアウトを学びました。

大画面をより活用したレイアウトになった

その後、アプリの中核品質ガイドラインに書いてある要件を満たしているかどうか確認することでアプリの品質をテストできることを学びました。

アプリの中核品質ガイドラインより一部抜粋

そして、modifierのtestTagを使用してコンポーザブルをテストする方法と、アノテーションを用いて画面サイズごとにテストをグループ化する方法を学びました。

テストをグループ化する手順は、
1.アノテーションクラスの作成

Compact, Medium, Expandedとサイズごとにアノテーションを作成

2.グループ化したいテストにアノテーションを付ける

画面がCompactな端末で行うテストに@TestCompactWidthを付ける

3.Android Studioテストランナーでレンチアイコンを押し、インストルメンテーション引数を設定する

レンチアイコンを押すと出現する画面
インストルメンテーション引数(ここではTestCompactWidth)を設定

用語

今回が初出で説明が足りていない重要な用語はありません

注意点

③ダイナミック ナビゲーションを使用してアダプティブ アプリを作成する

WindowSizeClass APIの依存関係の書き方が違う

Codelabsでは下のような依存関係を書くようにと指示されています。

...
dependencies {
...
"androidx.compose.material3:material3-window-size-class:$material3_version"
...

しかし、この書き方は勿論エラーが出るので、Implementation()で囲んでください。

...
dependencies {
...
implementation("androidx.compose.material3:material3-window-size-class")
...

また、Developersを調べると依存関係の書き方として以下のコードを推奨されますが、今回のアプリで使用するとエラーが発生します(エミュレータのAPIレベルが原因)。今回は使用しないでください。

implementation("androidx.compose.material3:material3-window-size-class:1.2.1")

手順に従ったのにタブレット画面が解答通りにならない(重要)

「7.アダプティブ ナビゲーション レイアウトを実装する」において、タブレット用の永続 / 固定ナビゲーション ドロワーを作成する作業があります。ここで、Codelabsの指示通りに進めると以下の画像の様にコンテンツが表示されません。

Codelabs通りに作成した場合のタブレット画面

ドロワーのコンテナの横のサイズが指定されていないことが原因です。そのため、PermanentNavigationDrawer コンポーザブルのdrawerContent パラメータを以下のように変更してください。

PermanentNavigationDrawer(
            drawerContent = {
                PermanentDrawerSheet(Modifier.width(dimensionResource(R.dimen.drawer_width))) {
                    NavigationDrawerContent(
                        selectedDestination = replyUiState.currentMailbox,
                        onTabPressed = onTabPressed,
                        navigationItemContentList = navigationItemContentList
                    )
                }
            }
        )

詳しく知りたい場合は以下のサイトをご覧ください

ナビゲーションレールを作成する際AnimatedVisibility コンポーザブルがboxコンポーザブルに囲まれている

CodelabsのコードではReplyAppContent コンポーザブルにboxコンポーザブルは存在しませんが、starterコードには存在します。困惑するかもしれませんが、boxコンポーザブルを消さずに作業を続けて問題ありません。

最終的なReplyAppContent コンポーザブル

④アダプティブ レイアウトでアプリを作成する

手順通りに文字列リソースを書いてもエラーが起きる

Codelabs内では、以下の様に書くことを指定しています。

R.string.navigation_bottom

しかし、ReplyAppTest.ktファイルでこの書き方をしてしまうとエラーが出ることがあります。
その場合はimport文に以下の文を加えてください

import com.example.reply.R

または文字列リソースの書き方を以下の様に書き換えてください。

com.example.reply.R.string.navigation_bottom

拡大画面の構成変更テストをするとエラーが出る(重要)

Codelabsの指示通りに拡大画面の構成変更テストを作成すると現時点では以下のようなエラーが出ると思います。

java.lang.AssertionError: Failed to assertAny(hasAnyDescendantThat(Text + EditableText contains 'Here are some great shots from my trip...' (ignoreCase: false)))
Reason: Expected exactly '1' node but could not find any node that satisfies: (TestTag = 'Details Screen')

エラー画面

ReplayDetailsScreen.kt内のReplyDetailsScreenコンポーザブルにtestTagメソッドがないことが原因です。以下の様に書き換えてください

@Composable
fun ReplyDetailsScreen(
    replyUiState: ReplyUiState,
    onBackPressed: () -> Unit,
    modifier: Modifier = Modifier,
    isFullScreen: Boolean = false,
) {
    BackHandler {
        onBackPressed()
    }
    Box(modifier = modifier) {
        LazyColumn(
            modifier = Modifier
                .testTag(stringResource(R.string.details_screen))
                .fillMaxSize()
                .background(color = MaterialTheme.colorScheme.inverseOnSurface)
                .padding(top = dimensionResource(R.dimen.detail_card_list_padding_top))
        ) {
...

アノテーション付きのテストのみ実行させる方法の説明が分かりにくい

確実に成功させるために、TestCompactWidth アノテーション付きのテストのみを実行するようにテストを構成します。
5.Android Studio テストランナーで、レンチアイコンをクリックしてテストを構成します。
6.テストの名前を「Compact Test」に変更し、[All in Package] でテストを実行するように選択します。

Codelabs「アダプティブ レイアウトでアプリを作成する」より

このレンチアイコンは、画面下部の[run]をクリックしたら左側に出現します。

Android Studio テストランナー画面
コンパクトテストの作成
▷でコンパクトテストの実行

さいごに

今回もCodelabsでの学習お疲れさまでした!
今回は演習が多かった為、普段よりも時間がかかったと思います。
次回はインターネットに接続してリモートのサーバーからデータを取得する方法についての内容です。これからの内容ではアプリ内に事前にあるデータではなく外部から入手したり新しく加えたりと更にアプリの幅を広げる内容となっています。この調子で頑張っていきましょう!!

この記事が気に入ったらサポートをしてみませんか?