Kotlin実践入門:中学受験歴史年号暗記アプリ作成チュートリアル

我が家の中学受験生からの依頼ですが、「歴史年号が多くて、なかなか覚えられないので、暗記アプリを作ってくれない?」ということです。子供の勉強にそれほど関心がありませんが、やっとお父さんの出番が来ました。週末二日間で、Kotlinの勉強からアプリ作成まで完成しました。App StoreまたはGoogle Playから無料ダウンロードできます。ぜひご活用ください。

中学受験
中学受験 App Store
Google Play

サンプルソースコードはgithubからダウンロードできます。
https://github.com/microstone-info/kotlinsample

初心者向けですが、本記事では下記の知識を紹介していきます。
・ Kotlinの基本文法
・ Android Studio基本の使い方
・ 画面遷移(Intent)の実装
・ リストビュー(ListView)の実装
・ イベント(Event)処理

1. Kotlin基本文法

KotlinはJetBrains社が開発したプログラミング言語であり、JVM(Java Virtual Machine)上実行されます。Javaとの交換性がありますが、Javaより文法が簡潔です。Javaプログラムは簡単にKotlinに移植できます。 様々なプログラミング言語がありますが、文法としてそんなに変わらなく、書き方が違うだけだと思います。

  • 1.1 書き方
    Javaと似ていますが、Kotlinでは文の後ろにセミコロンはいらないです。Javaに慣れた方は、文の後ろにセミコロンをつける癖があります。付けても別に問題がないです、IDEは警告が出るかもしれません。

  • 1.2 基本型
    Javaと違って、Kotlinはプリミティブ型がないです。すべてクラスのように扱えます。基本型は下記の通りです。ほかの言語とそんなに変わらないでしょう。
    Double / Float / Long / Int / Short / Byte / Char / Boolean / String

  • 1.3 変数
    変数定義はvarとval2種類があります、varが変更可能な変数です。valは変更不可変数です。また、変数定義は明示的に型を指定する場合、変数名の後ろに書きます。

 val a: String = "foo"
 a = "bar"              // エラー  

 var b: String = "foo"  
 b = "bar"              // OK
  • 1.4 Nullable
    普通の型はnullを入れられないです。nullを与える可能な変数を定義する場合、普通の型の後ろに「?」を付ける必要です。Swiftと同じように、NullPointerException例外を発生させないような対策ですが、慣れないと、面倒くさいと思います。
val a: String = null    // エラー
val b: String? = null   // OL
  • 1.5 制御構文
    if、while、forの構文はJavaとほとんど変わらないですが、switchは違います。kotlinでは「switch」ではなく、キーワードが「when」になります、breakもいらないです。
when (x) {
    1 -> print("x == 1")
    2 -> print("x == 2")
    else -> {
        print("x is neither 1 nor 2")
    }
}
  • 1.6 クラス定義
    クラスの定義はJavaと若干変わります、extends、implementsを使わなく、「クラス名:親クラスまたはインタフェース」の形になります。  
    メソッドは「fun」というキーワードで定義します。
class MyClassParentClass {
    var parameter: String

    fun myMethod(par: Int) {
        par++
        return par
    }
}
  • 1.7 その他
    プログラミング言語として細かい特徴が結構ありますが、ここで割愛します。本物のアプリを作りながら、ほかの言語との差異点を調べて早いと思います。

2. サンプル

これから下記のサンプルを実装します。「メイン画面」と「暗記画面」2画面があり、「メイン画面」はアプリのエントリです、「暗記画面」は歴史年号一覧画面になります。

  • 2.1 メイン画面
    メイン画面の特徴はデフォルトのタイトルを表示させない。「丸暗記」ボタンを押したら、「暗記画面」へ遷移します。「テスト」ボタンを押したら、「未実装」のメッセージが表示されます。
main
main
  • 2.2 暗記画面
    暗記画面はデフォルトのタイトルを表示させて、戻るボタンを追加します。戻るボタンを押しますと、メイン画面に戻します。
    ListViewを使って歴史イベント一覧を実現しまう。任意の歴史イベントを押したら、年号を非表示にして、もう覚えていると表します。もう1回押しますと、年号が再表示になります。
learn
learn

3. 開発環境

まず、開発環境を準備しましょう。下記のリンクから最新版のAndroid Studio(現在3.4.1)をダウンロードします。
https://developer.android.com/studio/index.html

4. 実践

本記事は主にkotlin画面切り替えやイベント処理を説明しますので、データモデルやデータ持続化処理を行わないです。最終的なプロジェクト構成は下記の通りです。

project
project

4.1 プロジェクト新規

  • 4.1.1 Android Studioを起動して,下記の画面が表示されます。「Start a new Android Studio project」を選択します。
new
new
  • 4.1.2 デフォルトの「Empty Activity」にしたまま,「Next」ボタンを押下します。
choose project
choose project
  • 4.1.3 プロジェクト名、パッケージ名、格納フォルダを自由に入れます。開発言語は「Kotlin」のままにして、「Finish」ボタンを押下します。
configure project
configure project
  • 4.1.4 プロジェクト雛形、依存ライブラリダウンロード、コンパイルは一連の処理が自動的に行われますので、しばらく待ちますと、下記の画面ができます。Hello Worldを表示するシングルページの雛形が作成されました。
    最も重要なファイルは「MainActivity」メインプログラム、layout配下の「activity_main.xml」画面レイアウト定義です。画面ごとにこの2つのファイルがペアで生成されます。
project
project

4.2 Activity追加

  • 4.2.1 メニューFileから下図のように新しいEmpty Activityを作ります。
New Activity
New Activity

  • 4.2.2 Activityの名前を「LearnActivity」して,「Finish」ボタンを押したら、Activityとレイアウト定義ファイルが自動生成されます。
Configure Activity
Configure Activity

4.3 画像用意

githubからダウンロードしたプロジェクトには「history.png」、「settings.png」、「title.png」画像3枚が入っています。この3枚の画像をdrawableにコピペします。

layout
layout

4.4 画面レイアウト

  • 4.4.1 メイン画面
    layout/activity_main.xmlレイアウト定義ファイルを開いて、下図のようにレイアウトを配置します。縦のLinearLayoutの中に2つの縦のLinearLayoutと横のLinearLayoutがを入れます。高さは1:5:2の比率で設定します。「丸暗記」ボタンのIDを「btnLearn」にし、「テスト」ボタンのIDを「btnTest」にします。具体的な設定が多いですので、gitlabからダウンロードしたサンプルを参照しながら調整してみてください。
main
main

  • 4.4.2 暗記画面
    layout/activity_learn.xmlレイアウト定義ファイルを開いて、下図のように左上のPalelte→LegacyからListViewを選択してレイアウトにドラッグ&ドロップします。ListViewの上下左右のマージンを0にします。layout_withとlayout_heightを「match_constraint」に設定して、設定後設定値が「0dp」になります。
learn
learn

4.5 ロジック実装

  • 4.5.1 メイン画面処理
    処理ロジックは下記の通りです、下記3点を注意してください(コメント箇所)。
    ① タイトル非表示
    ② 「丸暗記」ボタン押下時の画面切り替え処理
    ③ 「テスト」ボタン押下時のToastメッセージ表示処理
package com.example.myapplication

import android.content.Intent
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.widget.Toast
import Kotlinx.android.synthetic.main.activity_main.*

class MainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        // タイトル非表示
        val actionBar = supportActionBar
        actionBar!!.hide()

        // 丸暗記ボタン
        btnLearn.setOnClickListener{
            val intent = Intent(this, LearnActivity::class.java)
            startActivity(intent)
        }

        // テストボタン
        btnTest.setOnClickListener{
            Toast.makeText(applicationContext, "未実装", Toast.LENGTH_LONG).show()
        }
    }
}
  • 4.5.2 暗記画面処理
    処理ロジックは下記の通りです。この画面も下記3点を注意してください(コメント箇所)。
    ① 「戻る」ボタン表示、データ初期化処理
    ② 「戻る」ボタン押下後メイン画面への遷移処理
    ③ ListView行表示用のAdapter設定
    ④ ListView行クリックイベント処理
package com.example.myapplication

import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.view.MenuItem
import android.widget.SimpleAdapter
import android.widget.TextView
import Kotlinx.android.synthetic.main.activity_learn.*

class LearnActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_learn)

        // 戻るボタン表示
        supportActionBar?.setDisplayHomeAsUpEnabled(true)
        // タイトル設定
        supportActionBar?.title = "歴史年代丸暗記"

        // データ初期化
        val events: MutableList<Map<String, String>> = arrayListOf()
        events.add(mapOf("event" to "奴国王が後漢に使いを送り、金印を授かる""year" to "57"))
        events.add(mapOf("event" to "東大寺大仏開眼""year" to "752"))
        events.add(mapOf("event" to "空海が唐から帰国""year" to "806"))
        events.add(mapOf("event" to "関東大震災""year" to "1923"))

        // ListView行表示用Adapter設定
        listView.adapter = SimpleAdapter(this,
            events,
            android.R.layout.simple_expandable_list_item_2,
            arrayOf("event""year"),
            intArrayOf(android.R.id.text1, android.R.id.text2)
        )

        // 行クリックイベント処理
        listView.setOnItemClickListener { _, view, position, _ ->
            val data: Map<String, String> = events[position]
            val txtViewYear = view.findViewById<TextView>(android.R.id.text2)

            // 年号が表示になる場合、非表示に変わる。非表示になる場合、表示に変わる。
            if (txtViewYear.text == "") {
                txtViewYear.text = data["year"]
            } else {
                txtViewYear.text = ""
            }
        }
    }

    // 戻るボタン押下後メイン画面への遷移処理
    override fun onOptionsItemSelected(item: MenuItem?)Boolean {
        when (item?.itemId) {
            android.R.id.home -> finish()
            else -> return super.onOptionsItemSelected(item!!)
        }
        return true
    }
}

4.6 実行

  • 4.6.1 下図の実行ボタン(左4)またはデバッグボタン(左6)を押下して,自動的にコンパイルして実行されます。
menu
menu
  • 4.6.2 対象シミュレーターを選択して、「OK」ボタンを押下しますと、シミュレーターが起動され、アプリケーションが動きます。
    もしシミュレーターがなければ、左下の「Create New Virtual Device」を押下して,様々なバーチャルデデバイスを追加できです。
simulator
simulator

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

CAPTCHA