【Android Studio】Kotlinでつくるクイズアプリ講座 第2回「クイズ画面の作成」
今回はクイズ画面を作成していきます。
クイズ画面に必要なのは、この3つです。
- クイズ番号
- 問題文
- 解答ボタンを4つ
【完成イメージ】
1. クイズ番号
クイズ番号は「Q1」「第1問」という表示です。
2. 問題文
今回は県庁所在地クイズを作るので、問題文には「北海道、東京都」などの都道府県名を表示します。
3. 解答ボタン
4択クイズなので解答ボタンを4つ用意します。
例えば問題文が「北海道」のときは、解答ボタンに「札幌市」「仙台市」「金沢市」「奈良市」と表示します。
それでは activity_main.xml を開いてクイズ画面を作成していきましょう!
クイズ画面の作成
1. Code? Split? Design?
activity_main.xml を開くと、右上に3つのアイコンが並んでいます。
Android アプリ開発ではレイアウトを XML で書いていくのですが、このとき Code / Split / Design の3つの作成方法を選ぶことができます。
① Code(コード)
Code では自分で XML を書いていきます。
スッキリとした XML コードを書けることがメリットですが、慣れるまで少し手間がかかることがデメリットです。
② Split(スプリット)
Split では Code 画面とプレビュー画面が分割で表示されます。
左側に XML を書きながら、右側でレイアウトのプレビューを確認することができます。
③ Design(デザイン)
Design ではドラッグ&ドロップでボタンやテキストなどのビュー要素を置いていきます。ビュー要素を置くと自動的に activity_main.xml に XML コードが追加される仕組みです。
簡単に画面が作れるのがメリットですが、XML がゴチャゴチャするするのがデメリットです。
どれを使うか?
どれを使っても良いですが、慣れるまではコードがスッキリとする② Split がオススメです。
初めての方にもわかりやすいと思うので、今回は② Split でレイアウトを作っていきましょう。
プレビュー表示の設定
Split 画面を開くと、以下のようにプレビューが表示されているかもしれません。
この状態だと画面が見にくいので、いくつか設定を変更します。
プレビュー画面内のメニュー左上にある「青い正方形が重なったようなアイコン」をクリックして Design を選択します。
すぐ下にある「目のようなアイコン」をクリックして、Show System UI を選択します。
右下のボタンから拡大・縮小もできます。
2. レイアウトについて
activity_main.xml の2行目に
<androidx.constraintlayout.widget.ConstraintLayout
と書いてあります。
これは「ConstraintLayout(コンストレイント レイアウト)を使用します」という意味です。
アプリ画面にはテキスト・ボタン・画像などのビューを置いていきますが、このビューをどのように配置するのかを決めるのが「レイアウト」です。
Constraint は「相対的」という意味で、ConstraintLayout はあるビューを基準にしてもう1つのビューを配置するレイアウトです。
今回は
- ConstraintLayout は慣れるまで少し記述が難しいこと
- クイズ画面はボタンとテキストしかないこと
から ConstraintLayout ではなく LinearLayout(リニアレイアウト)を使います。
LinearLayout を使うとボタンやテキストを簡単に横一列・縦一列に並べることができます。
クイズ番号・問題文・解答ボタンを縦一列に並べて、クイズ画面を作成していきましょう。
3. LinearLayout(リニアレイアウト)
まずは activity_main.xml のコードを書き換えます。
追加・変更するのは、2・9・10・21行目です。
2・21行目
LinearLayout に変更して、21行目も LinearLayout で閉じます。
8行目
android:orientation="vertical"
LinearLayout 内のビュー要素を vertical(垂直方向)に並べる設定です。orientation を書かない場合は horizontal(水平方向)にビュー要素が並びます。
9行目
android:gravity="center"
ボタンやテキストなどの要素をcenter(中央)に配置する設定です。
右側のプレビューをみると「Hello World!」が画面中央に表示されています。
他にもこのような設定ができます。
android:gravity=”center_horizontal” | 左右中央 |
android:gravity=”center_vertical” | 上下中央 |
android:gravity=”center” | 上下左右中央 |
4. クイズ番号
今ある TextView「Hello World!」を以下のように書き換えます(3〜8行目)。
4行目
android:id="@+id/countLabel"
この TextView に id(名前)をつけています。id を書くことで MainActivity.kt からこの TextView を呼び出せるようになります。
5・6行目
android:layout_width="wrap_content"
android:layout_height="wrap_content"
TextView の width(幅)と height(高さ)を設定しています。
サイズの指定方法は3種類あります。
wrap_content | 文字数にあわせて幅・高さが調整されます。 |
match_parent | parent(親)レイアウトである LinearLayout と同じ幅・高さになります。 |
好きな数値 + dp | 300dp のように直接サイズを指定します。 dp は Density-independent Pixels の略で、画面密度に合わせてサイズを調整してくれる単位です。 |
7行目
android:text="Q1"
TextView に表示するテキストです。
文字が黄色に変わっていると思いますが、あとで修正するのでそのままにしておきます。
8行目
android:textSize="22sp"
テキストの文字サイズを指定しています。
sp は Scalable Pixel(スケーラブルピクセル)の略で、ユーザが設定しているフォントサイズに合わせてスケールが調整される単位です。
文字サイズの単位は sp と覚えておいて下さい。
5. 問題文
クイズ番号の下にコードを追加します(3〜9行目)。
クイズ番号のコードとほとんど同じですが、id が questionLabel になっています。
1つのアクティビティ内で同じ id を使うことはできないので、ビュー要素ごとに異なる id 名を付ける必要があります。
9行目
android:layout_marginTop="60dp"
問題文の上側に 60dp のマージン(余白)を付けています。
6. 解答ボタン
問題文の下にコードを追加します(3〜33行目)。
style属性
style="@style/Widget.Material3.Button.OutlinedButton"
あらかじめ用意されているボタンのスタイルを指定しています。
他にも色付きのボタン(デフォルト)、テキストだけのボタン(TextButton)が用意されています。
7. Warning の解消
これでレイアウトは完成ですが、いくつか文字が黄色くなっている箇所があります。
これは Warning といって「このコードは今後使えなくなるかもしれません」という非推奨コードのお知らせや「このコードも書いておいた方がいいですよ」という提案のようなものです。
そのままにしておいてもアプリの動作に影響はありませんが、コードがマーカーだらけだとあまり良い感じはしないので修正しておきましょう。
23行目あたり
1つ目は android:text=”問題文” の部分です。(Q1 はこの後修正していきます。)
色が変わっている部分にカーソルを合わせてみると
Hardcoded string "問題文", should use "@string" resource
と表示されます。
これは「ハードコードされている文字列 “問題文” には @string リソースを使うべきです」という Warning です。
@string リソースは文字列を定義するために用意されている strings.xml ファイルのことです。
ハードコードとは strings.xml を使わずに直接文字列を書いていることを指しています。
メッセージの通り strings.xml に文字列を定義していきましょう。
Android Studio 画面左側のプロジェクト構造から app → res → values → strings.xml を開きます。
strings.xml を開いたら、4行目のコードを追加します。
name 属性にこの文字列の名前を指定して、<string></string> の間に定義する文字列を書きます。
文字列を定義したら activity_main.xml に戻って
android:text="問題文"
を
android:text="@string/question_label"
に変更します。
@string/名前と書くことで、strings.xml に定義した文字列を呼び出すことができます。
Warning が消えたでしょうか?
16行目あたり
次は16行目あたりにある android:text=”Q1″ です。
先ほどの「問題文」と同じ方法で Warning を消すことができますが、少しだけ書き方が変わります。
Q1 の 1 の部分は第何問目かを表すので、クイズを出題するたびに更新します。このようにあとで数値を入れる部分には %d を使用します。これをプレースホルダーと言います。
strings.xml に5行目を追加します。
今回は数値なので %d ですが、文字列を入れる場合は %s を使用します。
activity_main.xml での書き方は同じで
android:text="@string/count_label"
と書きます。
31行目あたり
次はボタンの android:text=”選択肢” です。
これも strings.xml から文字列を指定していないことが原因なので、同じ方法で消していきましょう。
strings.xml に6行目を追加します。
activity_main.xml にもどって text 属性を変更します。
android:text="@string/btn_answer"
* 他の3つのボタンも @string/btn_answer を指定して Warning を消して下さい。
3行目
3行目のコードがグレーになっています。この画面には必要のないコードなので削除してしまいましょう。
その他
あと1つ Warning が残っているので修正します。
コード画面の右上にある黄色い!マークをクリックすると、画面下部にメッセージが表示されます。
全てのボタンに「選択肢」と表示しているので、「ボタンのテキストが重複しています」と書いてあります。
ボタンのテキストはあとから変更するので、ここでは提案を無視する設定をしましょう。
メッセージを選択した状態で左にある黄色い豆電球をクリックして、Suppress this check if it is false positive. をクリックします。
緑色のチェックマークが付いたら、全ての Warning を解消できています。
8. アプリを実行する
ここで一度アプリをエミュレータで実行してみましょう。
実行するエミュレータを確認して ▶️ のアイコンを押します。
このようなアプリ画面になっていれば成功です!
次に行うこと
クイズ画面のレイアウトは完成です!
次回はクイズを出題するための準備を進めていきましょう。
ここまでのコード
- strings.xml
-
<resources> <string name="app_name">QuizApp</string> <string name="question_label">問題文</string> <string name="count_label">Q%d</string> <string name="btn_answer">選択肢</string> </resources>
- activity_main.xml
-
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/main" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".MainActivity" android:orientation="vertical" android:gravity="center"> <TextView android:id="@+id/countLabel" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/count_label" android:textSize="22sp" /> <TextView android:id="@+id/questionLabel" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/question_label" android:textSize="24sp" android:layout_marginTop="60dp" /> <Button android:id="@+id/answerBtn1" style="@style/Widget.Material3.Button.OutlinedButton" android:layout_width="300dp" android:layout_height="60dp" android:layout_marginTop="80dp" android:text="@string/btn_answer" tools:ignore="DuplicateSpeakableTextCheck" /> <Button android:id="@+id/answerBtn2" android:layout_width="300dp" android:layout_height="60dp" android:text="@string/btn_answer" android:layout_marginTop="6dp" style="@style/Widget.Material3.Button.OutlinedButton" /> <Button android:id="@+id/answerBtn3" android:layout_width="300dp" android:layout_height="60dp" android:text="@string/btn_answer" android:layout_marginTop="6dp" style="@style/Widget.Material3.Button.OutlinedButton" /> <Button android:id="@+id/answerBtn4" android:layout_width="300dp" android:layout_height="60dp" android:text="@string/btn_answer" android:layout_marginTop="6dp" style="@style/Widget.Material3.Button.OutlinedButton" /> </LinearLayout>