この Codelab は、Android Kotlin の基礎コースの一部です。Codelab を順番に進めていくと、このコースを最大限に活用できます。すべてのコース Codelab は Android Kotlin の基礎 Codelab ランディング ページに掲載されています。
はじめに
多くのユーザーにとって使いやすいようにするため、アプリの開発自体が目的であっても、開発目的でも有用です。そのためには、複数の側面があります。
- RTL 言語のサポート。ヨーロッパや他の多くの言語は左から右に読まれます。それらのロケールのアプリは、通常、それらの言語に適しているように設計されています。アラビア語のように、多数の発話者がいる右から左に読む言語も多数あります。アプリを右から左に記述する(RTL)言語に対応させ、潜在的なユーザーを増やします。
- ユーザー補助をスキャンします。他の人にアプリを見られる可能性を推測するのは、落とし穴になるリスクもあります。ユーザー補助検証ツールは、当て推量の作業を排除してアプリを分析し、ユーザー補助機能を改善できる箇所を特定します。
- コンテンツの説明を含む TalkBack を設計します。視覚障がいは思っているよりも一般的で、視覚障がい者だけでなく、多くのユーザーがスクリーン リーダーを使用しています。コンテンツの説明は、ユーザーが画面内の要素を操作したときに読み上げるフレーズです。
- 夜間モードをサポートします。多くの視覚障がいのあるユーザーは、画面の色を変更することでコントラストを高め、アプリで視覚的に操作できます。Android では夜間モードを簡単にサポートできます。また、ユーザーがデフォルトの画面色をシンプルな方法で代替できるように、常に夜間モードをサポートする必要があります。
この Codelab では、これらの各オプションについて学習し、GDG Finder アプリにサポートを追加します。
また、チップを Android アプリで使用する方法についても学びます。チップを使用して、アプリにアクセスしやすくしながら、ユーザーの興味を引くことができます。
前提となる知識
以下について把握しておく必要があります。
- アクティビティとフラグメントを持つアプリを作成する方法と、データを渡すフラグメント間を移動する方法。
- ビューとビューグループを使用してユーザー インターフェース(特に RecyclerView)をレイアウトする。
- アーキテクチャ コンポーネント(
ViewModel
など)と推奨アーキテクチャを使用して、適切に構造化された効率的なアプリを作成する方法。 - データ バインディング、コルーチン、マウスクリックの処理方法。
- Room データベースを使用してインターネットに接続し、データをローカルにキャッシュする方法。
- ビューのプロパティを設定する方法と、リソースを XML リソース ファイルに抽出して使用する方法。
- スタイルとテーマを使用してアプリの外観をカスタマイズする方法
- マテリアル コンポーネント、ディメンション リソース、カスタム色の使用方法
学習内容
- 最大のユーザーがアプリを使用できるようにする方法
- 右から左に読む(RTL)言語でアプリの動作をサポートする方法
- アプリのユーザー補助機能を評価する方法
- コンテンツの説明を使用して、スクリーン リーダーでアプリの動作を改善する方法。
- チップの使用方法
- アプリをダークモードで動作させる方法。
演習内容
- 特定のアプリを評価、拡張してユーザー補助の改善を図るため、RTL 言語にも対応させます。
- アプリをスキャンしてユーザー補助機能の改善点を把握します。
- 画像の内容説明を使用する。
- ドローアブルの使用方法を学習します。
- 夜間モードを使用する機能をアプリに追加します。
GDG ファインダーのスターター アプリは、このコースでこれまでに学習したすべての内容に基づいています。
アプリは ConstraintLayout
を使用して 3 つの画面をレイアウトします。そのうち 2 つの画面は、Android での色とテキストの探索に使用するレイアウト ファイルです。
3 つ目の画面は GDG ファインダーです。GDG(Google デベロッパー グループ)は、Android を含む Google のテクノロジーに特化したデベロッパー コミュニティです。世界中の GDG が交流会、会議、研究ジャムなどのイベントを開催しています。
アプリを開発するときには、実際の GDG のリストを作成します。ファインダー画面は、デバイスの位置に基づいて GDG を距離順に並べ替えます。
お住まいの地域で GDG を利用されている場合は、ぜひウェブサイトにアクセスしてイベントに登録してください。GDG イベントは、他の Android デベロッパーと出会い、このコースに該当しない業界のベスト プラクティスを学ぶのに最適な方法です。
以下のスクリーンショットは、この Codelab の初めから終わりにアプリがどう変わるかを示しています。
左から右(LTR)言語と右から左(RTL)言語の主な違いは表示されるコンテンツの方向です。UI の方向が LTR から RTL に(またはその逆に)変更されると、多くの場合、ミラーリングと呼ばれます。ミラーリングは、テキスト、テキスト フィールド アイコン、レイアウト、経路を示すアイコン(矢印など)など、画面の大部分に影響します。それ以外のアイテム(数字(時計、電話番号)、方角がないアイコン(機内モード、Wi-Fi)、再生コントロール、ほとんどのグラフやグラフなど)はミラーリングされません。
RTL テキスト方向を使用する言語は、世界中で 10 億人以上が使用されています。Android デベロッパーは世界中にいるので、GDG Finder アプリは RTL 言語をサポートする必要があります。
ステップ 1: RTL サポートを追加する
このステップでは、GDG Finder アプリを RTL 言語と連携させます。
- この Codelab のスターター アプリである GDGFinderMaterial アプリをダウンロードして実行します。または、前の Codelab の最後のコードから続行します。
- Android マニフェストを開きます。
<application>
セクションに次のコードを追加して、アプリが RTL をサポートするように指定します。
<application
...
android:supportsRtl="true">
- [Design] タブで activity_main.xml を開きます。
- [Locale for Preview] プルダウン メニューから [Preview Right to Left] を選択します。(このメニューが表示されない場合は、ペインを広げるか、[属性] ペインを閉じて表示します)。
- [プレビュー] で、ヘッダー「GDG Finder」が右側に移動し、残りの画面はほぼ同じであることがわかります。全体として、この画面は合格です。しかし、テキストビューでは、右揃えではなく、左揃えになっているため、アライメントが正しくありません。
- デバイスでこれを使用するには、デバイスまたはエミュレータの [設定] で [開発者向けオプション] にある [RTL レイアウトを適用] を選択します。(開発者向けオプションを有効にする必要がある場合は、[ビルド番号] を探して、デベロッパーであることを示すトーストが表示されるまでクリックします。(デバイスと Android システムのバージョンによって異なります)
- アプリを実行して、メイン画面がプレビューと同じように表示されることを確認します。FAB が左側に切り替わり、右側に [Hamburger] メニューが表示されます。
- アプリでナビゲーション ドロワーを開き、[Search] 画面に移動します。以下の例のように、アイコンは左側にあり、テキストは表示されません。テキストが画面の左側、アイコンの左側に表示されます。これは、コードがビュー プロパティとレイアウト制約で左右の画面参照を使用しているためです。
ステップ 2: 左右ではなく開始と終了を使用する
「左」と「右」は、テキストの向きが変わっても、画面上で(画面に面したときに)変化しません。たとえば、layout_constraintLeft_toLeftOf
は常に要素の左側を画面の左側に制限します。アプリでは、上のスクリーンショットに示すように、テキストが RTL 言語で画面外に表示されます。
これを修正するには、「左」と「右」の代わりに、「Start
」と「End
」の用語を使用します。この用語は、現在の言語の方向に応じて、テキストの開始位置と終了位置を適切な位置に配置します。これにより、余白とレイアウトが画面の正しい領域に配置されます。
Open
list_item.xml。Left
とRight
への参照を、Start
とEnd
への参照に置き換えます。
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintStart_toEndOf="@+id/gdg_image"
app:layout_constraintEnd_toEndOf="parent"
ImageView
のlayout_marginLeft
をlayout_marginStart
に置き換えます。余白を正しい位置に移動して、アイコンを画面の端から離します。
<ImageView
android:layout_marginStart="
?
fragment_gdg_list.xml
を開きます。[Preview] ペインで GDG のリストを確認します。まだミラーリングされているため、アイコンの向きが正しくありません(アイコンがミラーリングされていない場合は、右から左へのプレビューを表示していることを確認してください)。マテリアル デザインのガイドラインに従い、アイコンをミラーリングしないでください。- res/drawable/ic_gdg.xml を開きます。
- XML コードの 1 行目で
android:autoMirrored="true"
を見つけて削除し、ミラーリングを無効にします。 - プレビューを確認するか、アプリを再度実行して、検索 GDG 画面を開きます。これでレイアウトが修正されます。
ステップ 3: Android Studio に作業を依頼する
前の演習では、RTL 言語をサポートする最初のステップを踏みました。幸いなことに、Android Studio がアプリをスキャンして、多くの基本的な項目を設定できます。
- list_item.xml の
TextView
で、layout_marginStart
をlayout_marginLeft
に戻して、スキャナが検出できるようにします。
<TextView
android:layout_marginLeft="@dimen/spacing_normal"
- Android Studio で [Refactor > Add RTL support where where you want.] をオンにして、マニフェストと、開始プロパティと終了プロパティを使用するレイアウト ファイルを更新するチェックボックスをオンにします。
- [Refactoring Preview] ペインで、app フォルダを見つけて、すべての詳細が表示されるまで展開します。
- アプリのフォルダの下に、先ほど変更した
layout_marginLeft
が、リファクタリングするコードとして表示されています。
- このプレビューには、システム ファイルとライブラリ ファイルも表示されます。[layout] と [ayout-watch-v20] と、[app] に含まれていないその他のフォルダを右クリックし、コンテキスト メニューから [Exclude] を選択します。
- 今すぐリファクタリングを行ってください。(システム ファイルに関するポップアップが表示された場合は、アプリコードに含まれていないフォルダをすべて除外していることを確認してください)。
layout_marginLeft
がlayout_marginStart
に戻されました。
ステップ 3: ロケールのフォルダを確認する
ここまでで、アプリで使用するデフォルトの言語の方向を変更しました。本番環境のアプリでは、strings.xml ファイルを翻訳者に送信して新しい言語に翻訳します。この Codelab では、アプリで strings.xml ファイルがスペイン語で提供されています(翻訳の生成には Google 翻訳を使用したため、完全ではありません)。
- Android Studio で、プロジェクト ビューを [Project Files] に切り替えます。
- [res] フォルダを展開すると、res/values と res/values-es フォルダが表示されます。フォルダ名の「\es」は、スペイン語の言語コードです。[values-"language code"] フォルダには、サポートされている各言語の値が含まれています。拡張機能のない values フォルダには、それ以外の場合に適用されるデフォルトのリソースが含まれています。
- values-es で strings.xml を開くと、すべての文字列がスペイン語であることがわかります。
- Android Studio で、[Design] タブで
activity_main.xml
を開きます。 - [Locale for Preview] プルダウンで、[Spanish] を選択します。テキストがスペイン語になりました。
- [省略可]RTL 言語に精通している場合は、その言語でvaluesフォルダとstrings.xmlを作成し、どのように表示されるかをテストします
- (省略可)デバイスの言語設定を変更して、アプリを起動します。元に戻せない言語に変更しないでください。この操作は元に戻せません。
前のタスクでは、アプリを手動で変更し、Android Studio を使用して RTL を改善したかどうかを確認しました。
アプリのユーザー補助機能を実現するには、ユーザー補助検証ツールが最適です。ターゲット デバイスのアプリをスキャンして、タップ ターゲットを大きくする、コントラストを上げる、アプリのユーザー補助機能を強化するための画像の説明など、改善案を提示します。ユーザー補助検証ツールは Google が開発し、Play ストアからインストールできます。
手順 1: ユーザー補助検証ツールをインストールして実行する
- Play ストアを開き、必要に応じてログインします。これは、物理デバイスまたはエミュレータで行うことができます。この Codelab ではエミュレータを使用します。
- Play ストアで「Accessibility Scanner by Google LLC」を検索します。スキャンするには多くの権限が必要になるため、Google が発行する正しいアプリを使用するようにしてください。
- スキャナをエミュレータにインストールします。
- インストールが完了したら、[開く] をクリックします。
- [Get Started] をクリックします。
- [OK] をクリックして、[設定] でユーザー補助検証ツールの設定を開始します。
- ユーザー補助検証ツールをクリックして、デバイスの [ユーザー補助] 設定に移動します。
- [サービスの使用] をクリックして有効にします。
- 画面上の手順に沿って、すべての権限を付与します。
- [OK] をクリックしてホーム画面に戻ります。画面上の任意の場所にチェックマークが付いた青いボタンが表示されることがあります。このボタンをクリックすると、フォアグラウンドでアプリのテストがトリガーされます。ボタンをドラッグして位置を変更できます。このボタンはアプリの上部に表示されるため、いつでもテストを開始できます。
- アプリを開くか、実行します。
- 青色のボタンをクリックして、追加のセキュリティ警告と権限を受け入れます。
ユーザー補助検証ツールのアイコンを初めてクリックしたときに、画面上にすべてを表示する権限をリクエストするメッセージが表示されます。これはとても怖い権限ですが、
このような権限は、決して絶対に許可しないでください。許可すると、アプリはメールを読んだり、銀行口座情報を取得したりできるようになるからです。ただし、ユーザー補助検証ツールが機能するためには、ユーザーの立場でアプリを検査する必要があります。そのため、この権限が必要となります。
- 青いボタンをクリックして、分析が完了するまで待ちます。下のスクリーンショットのように、タイトルと FAB が赤色で囲まれて表示されます。この画面に、ユーザー補助機能の改善に関する 2 つの提案が示されています。
- GDG Finder のボックスをクリックします。次のように、画像のコントラストに問題があることを示す追加情報がパネルに表示されます。
- [画像のコントラスト] の情報を展開すると、解決策が提案されます。
- 右矢印をクリックすると、次の項目の情報が表示されます。
- アプリの [GDG に申し込む] 画面に移動し、ユーザー補助検証ツールアプリでスキャンします。左側のように、多数の候補が表示されます。12 です。一部は類似アイテムと重複しています。
- 下のスクリーンショットのように、下部のツールバーにある「
」アイコンをクリックして、すべての提案のリストを表示します。この Codelab では、これらすべての問題に対処します。
Android ユーザー補助設定ツールには、アプリのユーザー補助機能を提供するツールが用意されています。TalkBack などのツールが含まれています。TalkBack は、音声、触覚、音声によるフィードバックを提供するスクリーン リーダーです。ユーザーは目を使わずにデバイスでコンテンツの操作や利用ができます。
TalkBack は視覚障がいのあるユーザーだけでなく、なんらかの視覚障がいのあるユーザーにも使用されていることがわかりました。目を休ませたいだけの人もいます。
ユーザー補助はすべての人を対象としています。このタスクでは、TalkBack を試して、正常に動作するようにアプリを更新します。
ステップ 1: ユーザー補助設定ツールをインストールして実行する
TalkBack は多くの物理デバイスにプリインストールされていますが、エミュレータにはインストールする必要があります。
- Play ストアを開きます。
- ユーザー補助設定を見つけます。Google が適切なアプリであることを確認します。
- インストールされていない場合は、ユーザー補助ツールをインストールします。
- デバイスで TalkBack を有効にするには、[設定 > ユーザー補助] に移動して [サービスを使用] を選択し、TalkBack を有効にします。ユーザー補助検証ツールと同様に、TalkBack で画面上のコンテンツを読み取るには権限が必要です。権限リクエストを承認すると、TalkBack を効果的に使用するためのチュートリアルのリストが表示されます。
- チュートリアルを止めないと、ここで一時停止してチュートリアルを終了できます。完了して TalkBack をオフにする方法をご確認ください。
- チュートリアルを終了するには、[戻る] ボタンをクリックして選択し、画面上の任意の場所をダブルタップします。
- TalkBack で GDG Finder アプリを使用します。画面やコントロールに関する有用な情報が TalkBack から得られない場面に注目してください。これは次の演習で修正します。
ステップ 2: コンテンツの説明を追加する
コンテンツ記述子は、ビューの意味を説明する説明的なラベルです。ほとんどのビューにコンテンツの説明を含める。
- GDG Finder アプリを実行し、Talback を有効にした状態で、[Apply to run GDG] 画面に移動します。
- メインの画像をタップしても、何も起こりません。
- add_gdg_fragment.xml を開きます。
- 次のように、
ImageView
にコンテンツ記述子属性を追加します。stage_image_description
文字列は strings.xml に含まれています。
android:contentDescription="@string/stage_image_description"
- アプリを実行します。
- [Apply to run GDG] に移動して画像をクリックします。画像の簡単な説明が表示されます。
- (省略可)アプリの他の画像にもコンテンツの説明を追加します。製品版のアプリの場合、すべての画像にコンテンツの説明を含める必要があります。
ステップ 3: 編集可能なテキスト フィールドにヒントを追加する
EditText
などの編集可能な要素については、XML で android:hint
を使用して、ユーザーが何を入力すべきか判断するのに役立ちます。ヒントは、入力フィールドのデフォルトのテキストであるため、常に UI に表示されます。
- 引き続き add_gdg_fragment.xml にします。
- 下記のコードをガイダンスとして使用し、コンテンツの説明とヒントを追加します。
textViewIntro
に追加します。
android:contentDescription="@string/add_gdg"
それぞれ編集テキストに追加します。
android:hint="@string/your_name_label"
android:hint="@string/email_label"
android:hint="@string/city_label"
android:hint="@string/country_label"
android:hint="@string/region_label"
- コンテンツの説明を
labelTextWhy
に追加します。
android:contentDescription="@string/motivation"
EditTextWhy
にヒントを追加します。編集ボックスにラベルを付けたら、ラベルに内容の説明を追加し、ボックスにヒントも追加します。
android:hint="@string/enter_motivation"
- 送信ボタンのコンテンツ説明を追加します。すべてのボタンには、ボタンが押された場合の動作についての説明が必要です。
android:contentDescription="@string/submit_button_description"
- Talback を有効にしてアプリを実行し、フォームに記入して GDG を実行します。
ステップ 4: コンテンツ グループを作成する
TalkBack がグループとして扱う UI コントロールには、コンテンツ グループを使用できます。グループ化された関連コンテンツは音声でアナウンスされます。これにより、支援技術のユーザーは、スワイプ、スキャン、頻繁な待ち時間を行わずに、画面上のすべての情報を確認できます。画面のコントロールの表示は変わりません。
UI コンポーネントをグループ化するには、LinearLayout
などの ViewGroup
にラップします。GDG Finder アプリでは、labelTextWhy
要素と editTextWhy
要素は意味的に結合するため、グループ化に最適です。
- add_gdg_fragment.xml を開きます。
LinearLayout
をLabelTextWhy
とEditTextWhy
でラップしてコンテンツ グループを作成します。下記のコードをコピーして貼り付けてください。このLinearLayout
には、必要なスタイルがすでに含まれています。(button
がLinearLayout
の外部にあることを確認してください)。
<LinearLayout android:id="@+id/contentGroup" android:layout_width="match_parent"
android:layout_height="wrap_content" android:focusable="true"
app:layout_constraintTop_toBottomOf="@id/EditTextRegion"
android:orientation="vertical" app:layout_constraintStart_toStartOf="@+id/EditTextRegion"
app:layout_constraintEnd_toEndOf="@+id/EditTextRegion"
android:layout_marginTop="16dp" app:layout_constraintBottom_toTopOf="@+id/button"
android:layout_marginBottom="8dp">
<!-- label and edit text here –>
<LinearLayout/>
- すべてのコードを適切にインデントするには、[コード &コードの再フォーマット] を選択します。
labelTextWhy
とeditTextWhy
からすべてのレイアウト マージンを削除します。labelTextWhy
で、layout_constraintTop_toTopOf
制約をcontentGroup
に変更します。
app:layout_constraintTop_toTopOf="@+id/contentGroup" />
editTextWhy
で、layout_constraintBottom_toBottomOf
制約をcontentGroup
に変更します。
app:layout_constraintBottom_toBottomOf="@+id/contentGroup"
EditTextRegion
とButton
をcontentGroup
に制約して、エラーを取り除きます。
app:layout_constraintBottom_toTopOf="@+id/contentGroup"
LinearLayout
に余白を追加します。必要に応じて、このマージンをディメンションとして抽出します。
android:layout_marginStart="32dp"
android:layout_marginEnd="32dp"
サポートが必要な場合は、解答コードの add_gdg_fragment.xml
と照らし合わせてコードを確認してください。
- アプリを実行し、TalkBack を使用して [Apply to run GDG] 画面を確認します。
ステップ 5: ライブ リージョンを追加する
現在、送信ボタンのラベルは [OK] です。フォームを送信する前にラベルと説明を 1 つ指定し、ユーザーがフォームをクリックして送信すると、別のラベルと説明に動的に変更することをおすすめします。そのためには、ライブ リージョンを使用します。
ライブ リージョンは、ビューが変更されたときにユーザーに通知するかどうかをユーザー補助サービスに示します。たとえば、パスワードの誤りやネットワーク エラーについてユーザーに通知することで、アプリを利用しやすくすることができます。この例では、シンプルにするため、送信ボタンの状態が変更されたときにユーザーに通知します。
- add_gdg_fragment.xml を開きます。
- 提供された
submit
文字列リソースを使用して、ボタンのテキストの割り当てを [Submit] に変更します。
android:text="@string/submit"
android:accessibilityLiveRegion
属性を設定して、ボタンにライブ リージョンを追加します。値を入力していく際には、複数の選択肢があります。変更の重要性に応じて、ユーザーに割り込みを行うかどうかを選択できます。「assertive」という値の場合、ユーザー補助サービスは進行中の音声を中断し、このビューの変更をすぐに通知します。値を “none” に設定した場合、変更はアナウンスされません。「礼儀」に設定すると、ユーザー補助サービスが変更を発表しますが、順番が来るのを待ちます。値を「丁寧」に設定します。
android:accessibilityLiveRegion="polite"
- add パッケージで、AddGdgFragment.kt を開きます。
showSnackBarEvent
Observer
内でSnackBar
を表示したら、ボタンに新しいコンテンツの説明とテキストを設定します。
binding.button.contentDescription=getString(R.string.submitted)
binding.button.text=getString(R.string.done)
- アプリを実行し、ボタンをクリックします。ボタンとフォントが小さすぎます。
ステップ 6: ボタンのスタイルを修正する
- add_gdg_fragment.xml で、ボタンの
width
とheight
をwrap_content
に変更し、ラベル全体を表示し、ボタンが適切なサイズになるようにします。
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- より優れたテーマのスタイルが使用されるように、ボタンから
backgroundTint
、textColor
、textSize
の各属性を削除します。 textViewIntro
からtextColor
属性を削除します。テーマカラーはコントラストが強い色にする必要があります。- アプリを実行します。[Submit] ボタンがさらに便利になりました。[送信] をクリックすると、[完了] に変わります。
チップは、属性、テキスト、エンティティ、アクションを表すコンパクトな要素です。ユーザーは、情報の入力、選択項目の選択、コンテンツのフィルタ処理、アクションの実行が可能です。
Chip
ウィジェットは、すべてのレイアウトと描画のロジックを含む ChipDrawable
のシンビュー ラッパーです。タップ、マウス、キーボード、ユーザー補助のナビゲーションをサポートする追加のロジックが存在します。メインチップと閉じるボタンは別々の論理サブビューとみなされ、独自のナビゲーション動作と状態が含まれます。
チップはドローアブルを使用します。Android ドローアブルを使用すると、画像、図形、アニメーションを画面に描画できます。ドローアブルは固定サイズにすることも、動的にサイズを設定することもできます。GDG アプリの画像などはドローアブルとして使用できます。また、ベクター図形描画を使用して、自由に描画できます。また、9-patch ドローアブルと呼ばれるサイズ変更可能なドローアブルもありますが、この Codelab では扱いません。drawable/ic_gdg.xml の GDG ロゴもドローアブル用です。
ドローアブルはビューではないため、ConstraintLayout
内に直接配置することはできません。ImageView
内に配置する必要があります。また、ドローアブルを使用してテキストビューやボタンの背景を提供したり、テキストの背後に背景を描画したりすることもできます。
ステップ 1: GDG のリストにチップを追加する
以下のチェックマークは、3 つのドローアブルを使用しています。背景とチェックマークはそれぞれドローアブルです。このチップをタップすると、リップル効果が作成されます。これは、状態の変化に応じてリップル効果を示す特別な RippleDrawable を使用して行います。
このタスクでは、GDG のリストにチップを追加し、GDG が選択されたときに状態を変更します。この演習では、[検索] 画面の上部に [チップ] というボタンの行を追加します。各ボタンが GDG リストをフィルタし、ユーザーが選択した地域からの結果のみを受け取るようにします。ボタンを選択すると、その背景が変わり、チェックマークが表示されます。
- fragment_gdg_list.xml を開きます。
HorizontalScrollView.
のsingleLine
プロパティ内にcom.google.android.material.chip.ChipGroup
を作成してtrue
に設定し、すべてのチップを横方向にスクロールできる 1 行で並べます。一度に 1 つのチップしか選択できないように、singleSelection
プロパティをtrue
に設定します。コードは次のとおりです。
<com.google.android.material.chip.ChipGroup
android:id="@+id/region_list"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:singleSelection="true"
android:padding="@dimen/spacing_normal"/>
- [layout] フォルダに region.xml という新しいレイアウト リソース ファイルを作成し、1 つの
Chip
のレイアウトを定義します。 - region.xml で、すべてのコードを以下のように 1 つの
Chip
のレイアウトに置き換えます。このChip
はマテリアル コンポーネントであることに注意してください。また、チェックマークapp:checkedIconVisible
をオンにすると、selected_highlight
カラーがないと、エラーが発生します。
<?xml version="1.0" encoding="utf-8"?>
<com.google.android.material.chip.Chip
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
style="@style/Widget.MaterialComponents.Chip.Choice"
app:chipBackgroundColor="@color/selected_highlight"
app:checkedIconVisible="true"
tools:checked="true"/>
- 欠落している
selected_highlight
色を作成するには、selected_highlight
の上にカーソルを置き、インテント メニューを表示し、選択したハイライトのカラーリソースを作成します。デフォルトのオプションのままなので、[OK] をクリックします。ファイルは res/color フォルダに作成されます。 - res/color/selected_highlight.xml を開きます。この色状態リストでは、
<selector>
としてエンコードされており、状態ごとに異なる色を指定できます。各状態とそれに対応する色は、<item>
としてエンコードされます。これらの色の詳細については、色テーマの設定をご覧ください。
<selector>
内で、デフォルトの色colorOnSurface
を持つ項目を状態リストに追加します。状態リストでは、すべての状態を常にカバーすることが重要です。たとえば、デフォルト色を設定します。
<item android:alpha="0.18" android:color="?attr/colorOnSurface"/>
- デフォルトの色より上に、色が
colorPrimaryVariant
のitem
を追加し、使用状態をtrue
に選択した場合にのみ制約を適用します。状態リストは、ケース ステートメントのように上から下に順に処理されます。いずれの状態も一致しない場合、デフォルトの状態が適用されます。
<item android:color="?attr/colorPrimaryVariant"
android:state_selected="true" />
ステップ 2: チップの行を表示する
GDG アプリは、GDG のあるリージョンを示すチップのリストを作成します。チップを選択すると、アプリは結果をフィルタして、その地域の GDG の結果のみを表示します。
- search パッケージで GdgListFragment.kt を開きます。
onCreateView()
のreturn
ステートメントのすぐ上にviewModel.regionList
にオブザーバーを追加し、onChanged()
をオーバーライドします。ビューモデルで提供されるリージョンのリストが変更されたら、チップを再作成する必要があります。指定されたdata
がnull
の場合にすぐに返すステートメントを追加します。
viewModel.regionList.observe(viewLifecycleOwner, object: Observer<List<String>> {
override fun onChanged(data: List<String>?) {
data ?: return
}
})
onChanged()
の null テストの下で、binding.regionList
をchipGroup
という新しい変数に割り当てて、regionList
をキャッシュに保存します。
val chipGroup = binding.regionList
- 下記で、
chipGroup.context
からチップをインフレートするための新しいlayoutInflator
を作成します。
val inflator = LayoutInflater.from(chipGroup.context)
- databinding エラーを解消するには、プロジェクトをクリーンアップして再ビルドします。
インフレータの下で、実際のチップを(regionList
の各リージョンに 1 つずつ)作成できます。
- すべてのチップを保持するための変数
children
を作成します。各チップを作成して返すため、data
で渡されたマッピング関数を割り当てます。
val children = data.map {}
- 地図のラムダ内で、
regionName
ごとにチップを作成してインフレートします。完成したコードは以下のとおりです。
val children = data.map {
val children = data.map { regionName ->
val chip = inflator.inflate(R.layout.region, chipGroup, false) as Chip
chip.text = regionName
chip.tag = regionName
// TODO: Click listener goes here.
chip
}
}
- ラムダ内で、
chip
を返す直前にクリック リスナーを追加します。chip
をクリックしたら、その状態をchecked
に設定します。viewModel
のonFilterChanged()
を呼び出します。これにより、このフィルタの結果を取得する一連のイベントがトリガーされます。
chip.setOnCheckedChangeListener { button, isChecked ->
viewModel.onFilterChanged(button.tag as String, isChecked)
}
- ラムダの最後に、
chipGroup
から現在のビューをすべて削除し、children
からすべてのチップをchipGroup
に追加します。(チップを更新できないため、chipGroup
の内容を削除して再作成する必要があります)。
chipGroup.removeAllViews()
for (chip in children) {
chipGroup.addView(chip)
}
完成したオブザーバーは次のようになります。
override fun onChanged(data: List<String>?) {
data ?: return
val chipGroup = binding.regionList
val inflator = LayoutInflater.from(chipGroup.context)
val children = data.map { regionName ->
val chip = inflator.inflate(R.layout.region, chipGroup, false) as Chip
chip.text = regionName
chip.tag = regionName
chip.setOnCheckedChangeListener { button, isChecked ->
viewModel.onFilterChanged(button.tag as String, isChecked)
}
chip
}
chipGroup.removeAllViews()
for (chip in children) {
chipGroup.addView(chip)
}
}
})
- アプリを実行し、GDGS を検索して [Search] 画面を開き、新しいチップを使用します。各チップをクリックすると、アプリの下にフィルタ グループが表示されます。
夜間モードを使用すると、デバイスの設定で、夜間モードを有効にするなどのように、色をダークモードに変更できます。夜間モードでは、アプリはデフォルトの明るい背景を暗く変更し、それに応じて他のすべての画面要素も変更する。
ステップ 1: 夜間モードを有効にする
アプリにダークモードを設定するには、そのテーマを Light
テーマから DayNight
というテーマに変更します。DayNight
のテーマは、モードに応じてライトテーマまたはダークテーマで表示されます。
styles.xml,
で、AppTheme
の親テーマをLight
からDayNight
に変更します。
<style name="AppTheme" parent="Theme.MaterialComponents.DayNight.NoActionBar">
MainActivity
のonCreate()
メソッドで、AppCompatDelegate.setDefaultNightMode()
を呼び出してプログラムでダークテーマを有効にします。
AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_YES)
- アプリを実行し、ダークモードに切り替わったことを確認します。
ステップ 2: 独自のダークテーマ カラーパレットを生成する
ダークテーマをカスタマイズするには、ダークテーマで使用する -night
修飾子を持つフォルダを作成します。たとえば、夜間モードで特定の色を設定するには、values-night
というフォルダを作成します。
- material.io カラー選択ツールにアクセスして、夜間テーマのカラーパレットを作成します。たとえば、濃い青色の色をベースにできます。
- colors.xml ファイルを生成してダウンロードします。
- [Project Files] ビューに切り替えると、プロジェクト内のすべてのフォルダが一覧表示されます。
- 「res」フォルダを見つけて展開します。
- res/values-night リソース フォルダを作成します。
- 新しい colors.xml ファイルを res/values-night リソース フォルダに追加します。
- 夜間モードを有効にしたままアプリを実行すると、res/values-night に定義した新しい色が使用されます。チップは新しいセカンダリ カラーを使用します。
Android Studio プロジェクト: GDGFinderFinal。
RTL 言語のサポート
- Android マニフェストで、
android:supportsRtl="true"
を設定します。 - RTL はエミュレータでプレビューでき、画面レイアウトは任意の言語で確認できます。デバイスまたはエミュレータで、[設定] を開き、[開発者向けオプション] で [RTL レイアウトを適用] を選択します。
Left
とRight
への参照を、Start
とEnd
への参照に置き換えます。- ドローアブルのミラーリングを無効にするには
android:autoMirrored="true"
を削除します。 - [Refactor] > [可能であれば RTL サポートを追加する] を選択すると、Android Studio が自動的に処理します。
- values-&language_Code フォルダを使用して、言語固有のリソースを保存します。
ユーザー補助のスキャン
- Play ストアで Google LLC のユーザー補助検証ツールを入手し、画面要素をスキャンして改善を行います。
内容説明で TalkBack を設計する
- Google が開発した Android ユーザー補助設定ツール(TalkBack を含む)をインストールします。
- すべての UI 要素にコンテンツの説明を追加する。次に例を示します。
android:contentDescription="@string/stage_image_description"
EditText
などの編集可能な要素については、XML でandroid:hint
属性を使用して、入力するテキストに関するヒントをユーザーに示します。- 関連する要素をビューグループにラップしてコンテンツ グループを作成します。
- ライブ リージョンを作成し、
android:accessibilityLiveRegion
を使用してユーザーに追加のフィードバックを提供する。
チップを使用してフィルタを実装する
- チップは、属性、テキスト、エンティティ、アクションを表すコンパクトな要素です。
- チップのグループを作成するには、
com.google.android.material.chip.ChipGroup
を使用します。 - 1 つの
com.google.android.material.chip.Chip
のレイアウトを定義します。 - チップで色を変更する場合は、次のように色状態リストをステートフルな色の
<selector>
として指定します。<item android:color="?attr/colorPrimaryVariant"
android:state_selected="true" /> - ビューモデル内のデータにオブザーバーを追加して、チップをライブデータにバインドします。
- チップを表示するには、チップグループのインフレータを作成します。
LayoutInflater.from(chipGroup.context)
- チップを作成して、目的のアクションをトリガーするクリック リスナーを追加し、チップをチップグループに追加します。
ダークモードをサポートする
- ダークモードをサポートするには、
DayNight
AppTheme
を使用します。 - ダークモードはプログラムで設定できます。
AppCompatDelegate.setDefaultNightMode()
- ダークモードの色と値をカスタマイズするには、res/values-night リソース フォルダを作成します。
Android デベロッパー ドキュメント:
LayoutDirection
(RTL)- 双方向性
- ユーザー補助検証ツールのスタートガイド
- TalkBack
- TalkBack ジェスチャー
- ドローアブルの概要ドキュメント
- コンテンツ記述子
- コンテンツ グループ
- ライブ リージョン
- NinePatch ドローアブル
- Draw 9-patch ツール
- チップ
ChipGroup
- ダークモード
- カラーテーマ設定
- カラーツール
- ドローアブル グラフィックをアニメーションにする
その他のリソース:
- Kotlin による Android アプリの開発(Udacity コース)
- プログラマー向け Kotlin ブートキャンプ(Udacity コース)
- プログラマー向け Codelab ブートキャンプ Codelab
このセクションでは、インストラクターが主導するコースの一環として、この Codelab に取り組む生徒の課題について説明します。教師は以下のことを行えます。
- 必要に応じて課題を割り当てます。
- 宿題の提出方法を生徒に伝える。
- 宿題を採点します。
教師はこれらの提案を少しだけ使うことができます。また、他の課題は自由に割り当ててください。
この Codelab にご自分で取り組む場合は、これらの課題を使用して知識をテストしてください。
問題 1
RTL 言語をサポートするために必要なことは次のうちどれですか。
▢ プロパティ内の Left
と Right
を Start
と End
に置き換える
▢ RTL 言語に切り替えること
▢ すべてのアイコンが android:autoMirrored="true"
を使用していることを確認する
▢ コンテンツの説明を提供する
質問 2
次の Android デバイスに組み込まれているユーザー補助ツールは次のうちどれですか。
▢ TalkBack
▢ ユーザー補助検証ツール
▢ Android Studio のリファクタリング > 可能であれば RTL サポートを追加する
▢ lint
問題 3
チップの説明として正しくないものは次のうちどれですか。
▢ チップを ChipGroup
の一部として表示します。
▢ ChipGroup
の色の状態リストを指定できます。
▢ チップとは、入力、属性、アクションを表すコンパクトな要素です。
▢ アプリがチップを使用する場合は、必ず DarkTheme
を有効にしておく必要があります。
問題 4
ダークモードとライトモードのスタイル設定に使用するテーマはどれですか。
▢ DayNight
▢ DarkTheme
▢ DarkAndLightTheme
▢ Light
問題 5
ライブ リージョンとは何ですか。
▢ ユーザーにとって重要な情報を含むノード
▢ マテリアル ガイドラインに沿って形状が変わる画面領域
▢ 動画のストリーミングを可能にするビュー
▢ アニメーション ドローアブル