Android Studio + kotlin + SQLiteで音符フラッシュカードアプリを作る　④画面デザイン～結果画面（Linear Layoutその2）～


#１．今回のテーマ
画面デザイン編3回目、ゲーム結果画面について書いていきます。

画面はこんな感じです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/619303/9a59b925-baeb-6e21-9306-1d360233dab5.png)

上部に「結果」というラベル。
その下に、「レベル」「正解数」「タイム」「日付」「名前」を表示する部品。
そして「保存」「もう一度」「トップへ」という3種類のボタン、という構成です。

android studioではこんな感じです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/619303/4c6b13eb-2d0c-fff7-70df-fa6298936890.png)

余談ですが、このスクリーンショットは「Shift」キー＋「windows」ボタン＋「S」キーのショートカットコマンドで取っています。
業務でテストエビデンスを取る際などに「Print Screen」キー、あるいは「Alt」キー＋「Print Screen」キーを使う方は多いと思いますが、あまり知られていないのが、この「Shift」＋「windows」＋「S」です。

違いを簡単に説明します。
「Print Screen」単体
　　⇒画面全体のスクリーンショット。不要なウィンドウまで含まれてしまう。
「Alt」＋「Print Screen」
　　⇒アクティブなウィンドウのみのスクリーンショット。まぁまぁ便利。
「Shift」＋「windows」＋「S」
　　⇒任意の範囲のスクリーンショット。超便利。

キーの配置的に、慣れるまでは押しづらいですが、慣れたらもう手放せないくらい便利です。
挙動はこんな感じです。
「Shift」＋「windows」＋「S」（Shiftとwindowsを押しながら、Sを最後に押します）を押すと下のように画面が暗くなります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/619303/0f1c0506-7d30-5ab4-e2f8-4e0afb74ffd6.png)

そして、スクリーンショットを取りたい範囲をマウスで選んでいきます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/619303/7e054c06-4e2f-1d69-7273-18751f01060c.png)

これでクリップボードに選択した範囲のコピーが取れます。
後は貼り付けたい場所にCtrl＋Vで貼れば完了。
今までは一度Excelに張り付けて不要な部分をトリムして、なんてことをしてましたが、これを使えば一発です。

私は楽をするために結構いろいろとショートカットキーを調べたので、「意外と知られていない便利なwindowsショートカットキー」というテーマで1記事書けてしまいそうです。

話が逸れましたが、本日のテーマに入っていきたいと思います。

結果画面についても、前回のゲーム画面と同じくLinear Layoutで書いていきます。
スクリーンショットでもわかるように規則正しく部品が並んでいるだけで、複雑さはあまりないですね。
なのでLinear Layoutで十分書いていけると判断しました。



#２．画面全体の説明
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/619303/178bb52f-a0ae-ddfb-5132-1243cba48ecd.png)
大外の赤枠の内側に、9個の黄色枠が配置されています。
赤枠全体で見ると、各アイテムは縦並び、黄色枠内は横並びになっています。
なので、前回同様Linear Layoutを2つ入れ子にすれば表現できます。



#３．大外の赤枠定義

では大外の赤枠の定義から。

```xml:activity_result.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">
```

決まり文句です。ゲーム画面と全く同じです。

widthで幅、heightで高さ。両方ともmatch_parentで「画面全体に準ずる」という定義です。
並びはorientation属性に「vertical」と設定することで、「縦並び」と宣言します。

以上。

#４．「結果」ラベル
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/619303/fa0d2b84-d9b7-f0e9-abd7-308e71837127.png)
「結果」という文字列をTextViewで表示しているだけです。
文字列はstrings.xmlに定義でしたね。

```xml:strings.xml
<string name="label_result">結果</string>
```

```xml:activity_result.xml
    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="24dp"
        android:layout_marginLeft="150dp"
        android:text="@string/label_result"
        android:textSize="48dp"/>
```
strings.xmlで「label_result」という変数に「結果」という文字列を設定して、activity_result.xmlのtext属性に「label_result」設定しています。
strings.xmlで定義した文字列を使うときは「@string/」を頭につけることも忘れずに。
幅・高さはコンテンツ（＝今回は文字の大きさ）に準拠。
余白は上：24dp、左：150dpをそれぞれセット。
文字の大きさは48dpです。


#５．「レベル」
続いて、レベルです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/619303/147650a3-b982-b7c3-1e8e-df02b5db698c.png)
2つの部品で構成されています。
「レベル」という文字列を単純に表示する左側の部分と、トップ画面で選択したレベルを表示する右側の部分で構成されています。
左側はただ表示するだけなので、先ほど説明した「結果」ラベルと同様にstrings.xmlで「レベル：」という文字列を定義して、それをtext属性にセットするだけです。
一方、右側は、トップ画面で選択されたレベルに応じて表示内容を変える必要があります。つまりプログラムで処理を書いていかなければなりません。
従って、これまでの画面と同じようにidの設定が必要です。

それから、忘れてはならないのが、この2つの部品は「横並び」だということです。
なので、新たに横並びのLinear Layoutタグを始める必要があります。

先に解説を入れましたが、具体的なコードは以下になります。

```xml:strings.xml
    <string name="label_level">レベル：</string>
```

```xml:activity_result.xml
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="24dp"
        android:orientation="horizontal">
⇒横並びのLinear Layout開始を宣言


        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginLeft="48dp"
            android:text="@string/label_level"
            android:textSize="24dp"/>
⇒strings.xmlのlabel_levelをセット。

        <TextView
            android:id="@+id/tvLevel"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginLeft="8dp"
            android:text="右手初級"
            android:textSize="24dp"/>
⇒初期値はべた書きで「右手初級」。
　idはtvLevelとしました。

    </LinearLayout>
⇒ここまでで横並び終了。
```

#６．「正解数」「タイム」「日付」
特筆すべき箇所はありません。これまでと同様横並びが必要な場合はLinear Layoutを開始。プログラムで値を設定する部品にはidを設定。表示させる文字列はstrings.xmlで定義してtext属性にセット、です。

コードだけ掲載しておきます。

```xml:activity_result.xml
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="8dp"
        android:orientation="horizontal">


        <TextView
            android:id="@+id/label_correctCount"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginLeft="48dp"
            android:text="@string/label_correct_count2"
            android:textSize="24dp"/>

        <TextView
            android:id="@+id/tvCorrectCount"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginLeft="8dp"
            android:text="00"
            android:textSize="24dp"/>

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginLeft="8dp"
            android:text="@string/label_question_count"
            android:textSize="24dp"/>

    </LinearLayout>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="8dp"
        android:orientation="horizontal">

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginLeft="48dp"
            android:text="@string/label_time2"
            android:textSize="24dp"/>

        <TextView
            android:id="@+id/tvTime"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginLeft="8dp"
            android:text="00:00.0"
            android:textSize="24dp"/>

    </LinearLayout>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="8dp"
        android:orientation="horizontal">

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginLeft="48dp"
            android:text="@string/label_date2"
            android:textSize="24dp"/>

        <TextView
            android:id="@+id/tvDate"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginLeft="8dp"
            android:text="yyyy/mm/dd"
            android:textSize="24dp"/>

    </LinearLayout>
```


#７．「名前」
次に名前です。名前はゲーム結果を保存したいときにこの結果画面から入力できるようにします。
文字を入力させたい場合は、EditTextアイテムを使います。

```xml:activity_result.xml
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="8dp"
        android:orientation="horizontal">

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginLeft="48dp"
            android:text="@string/label_name2"
            android:textSize="24dp"/>

        <EditText
            android:id="@+id/etName"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginLeft="8dp"
            android:text="@string/label_default_name"
            android:maxLength="5"
            android:maxLines="1"
            android:inputType="text"
            android:textSize="24dp"/>

    </LinearLayout>
```

新しい属性がいくつか出てきているので、順に解説します。

maxLength
⇒文字の最大長です。5文字までしか入力できないように制限しました。

maxLines
⇒EditTextビューに文字を入力する際に、EditTextビューが広がる最大の行数のこと。
入力できる最大の行数ではないことに注意
紛らわしいですね。
イメージをつかみやすいように、LINEのスクリーンショットで解説します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/619303/9e12fc91-0f20-dc6a-abc0-c1bf63af4b58.png)
この例では3行入力していて、入力欄の3行まで広がっていますが、maxLinesを1にすると、入力自体は何行でもできますが、入力欄は1行だけしか表示されません。
例えばMaxLinesを1にすると、2行目以上入力はできますが表示可能なのは1行ずつで、2行目以降に入力された内容を確認する際は、ビューをスクロールさせないとできないことになります。

inputType
入力可能な行数を制限しているのが、このinputTypeです。
今回の名前入力は「1行だけ」という制限をかけました。
1行に制限するための設定値が、「text」です。
これだけ見ると、「このEditViewに入力可能なのは文字列です」、と宣言しているだけで、複数行の入力を禁止しているようには見えませんね。
他の設定値を見るとイメージが付きやすいと思います。
いくつか例を挙げます。
・textMultiLine
　⇒これが複数行文字列を入力可能にしたい場合の設定値になります。
　　textは1行だけ、複数行はtextMultiLineです。
・phone
　⇒電話番号を入力させたい場合。キーボードがテンキー表示になります。
・textEmailAddress
　⇒メールアドレスを入力させたい場合。英数字キーボードになります。
その他にもいろいろな設定値があります。
以下の記事がわかりやすいです。
https://qiita.com/joji/items/41cc6cbedb7b84b632df



#８．「保存」「もう一度」「トップへ」
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/619303/55bcfad3-d729-bcd6-7826-0bc34927ba16.png)

こちらはボタンを縦に3つ並べているだけです。
縦並びなのでLinear Layoutを入れ子にする必要もありません。

```xml:activity_result.xml
    <Button
        android:id="@+id/btSave"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="16dp"
        android:layout_marginLeft="64dp"
        android:text="@string/label_save"
        android:textSize="24dp"/>

    <Button
        android:id="@+id/btAgain"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="8dp"
        android:layout_marginLeft="64dp"
        android:text="@string/label_again"
        android:textSize="24dp"/>

    <Button
        android:id="@+id/btToTop"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="8dp"
        android:layout_marginLeft="64dp"
        android:text="@string/label_toTop"
        android:textSize="24dp"/>
```
いずれも後程処理を実装するのでidを設定、表示する文字列はstrings.xmlで定義、とこれまで解説済みの内容だけで記載していますので、改めての解説は割愛します。

最後に全体赤枠のLinear Layoutを閉じて終わりです。

```xml:activity_result.xml
</LinearLayout>
```

今回は以上です。
次回からは処理実装編です！



[①概要](https://qiita.com/tomohiro-yamashita-5664/items/e87f90fef9cf34faf9bf)
[②画面デザイン～トップ画面（Constraint Layout）～](https://qiita.com/tomohiro-yamashita-5664/items/72a529e12f292a8e1538)
[③画面デザイン～ゲーム画面（Linear Layout）～](https://qiita.com/tomohiro-yamashita-5664/items/9674fa7c1d0cc2de1c40)
[④画面デザイン～結果画面（Linear Layoutその2）～（本記事）](https://qiita.com/tomohiro-yamashita-5664/items/08f99be14d2ac2254634)
[⑤トップ画面からの遷移（インテント(putExtra)）](https://qiita.com/tomohiro-yamashita-5664/items/ae86d6273cfc8c13b482)
[⑥トップ画面から引き継いだデータ表示（インテント(getExtra)）](https://qiita.com/tomohiro-yamashita-5664/items/bf50791fa5355818d7fb)
[⑦問題出題（ロジック実装）](https://qiita.com/tomohiro-yamashita-5664/items/a67eeb3fe9cc63eb1c65)
[⑧回答ボタン押下（効果音再生（MediaPlayer、正誤判定、次の問題出題）](https://qiita.com/tomohiro-yamashita-5664/items/8b032855a9377ba9897e)
[⑨タイムカウンターの実装（handler）](https://qiita.com/tomohiro-yamashita-5664/items/8f5633e68f0519d6841f)
[⑩ゲーム画面から引き継いだゲーム結果表示（インテント）](https://qiita.com/tomohiro-yamashita-5664/items/0e208a3c1a75c5b13376)
[⑪当日日付データ取得](https://qiita.com/tomohiro-yamashita-5664/items/59513080e5d5f419d6af)
[⑫DB保存（SQLite、Insert）](https://qiita.com/tomohiro-yamashita-5664/items/5a0d967f2e42aa90ee24)
⑬もう一度、トップ画面へ戻るボタン（インテント）
⑭ランキング表示（SQLite、Select）
⑮実機でのテスト
⑯Google Playで公開