【簡単】KotlinでAndroidアプリ開発入門・GUI電卓アプリ作成

プログラミング
質問する人
質問する人

KotlinでAndroidアプリを作成してみたい。GUIの電卓とか作ってみたいな。

こんなご要望にお応えします。

◆この記事の内容
・KotlinでAndroidアプリ(電卓)を作成する方法が分かります
・Android Studioのセットアップの方法が分かります
・Android端末の実機とエミュレータのセットアップが分かります
うまし
うまし

エンジニア歴15年のうましが解説します。

スポンサーリンク

Kotlinを使用したGUIアプリ(電卓)の作成

Androidの公式の開発言語でもあるKotlinを使用して簡単なGUIアプリ(電卓)を作成する手順をご紹介します。こちらのサイトを参考にさせて頂き、NULL安全化、アプリのレイアウトが崩れる対策などを加えました。完成したイメージはこちらです。

android電卓完成イメージ

【筆者の環境】
・Android Studio Chipmunk | 2021.2.1 Patch 1
・Windows 10 64bit

Android Studioのインストール

こちらから最新のAndroid Studioをダウンロードします。『Download Android Studio』をクリックすると規約が表示されます。同意したら下のチェックを入れて『Download Android Studio Chipmunk (バージョン名) for Windows』をクリックするとインストーラーがダウンロードされますので実行してください。

android_studio_インストール1

インストールはとても簡単で、インストーラーを起動したら基本的にはデフォルト(そのまま)の状態で『Next』で進むだけです。悩む部分は少ないかと思います。

android_studio_インストール2

プロジェクトの作成

『New Project』をクリックします。

android_studio_kotlin電卓1

『Empty Activity』を選択してNextで進みます。

android_studio_kotlin電卓2

デフォルト(そのまま)の状態で『Finish』クリックしてください。

android電卓プロジェクト作成1

初回起動時は開発環境のセットアップが始まります。終わったら右下の『Finish』をクリックしてください。

初回起動

セットアップが完了すると自動で以下の画面が表示されて、実際のプログラミングに移ります。初回起動やパソコンのスペックによっては数分かかる場合もあります。

初期画面

アプリのレイアウト

最初に起動する『activity_main.xml』を選択してください。閉じた場合は、左のツリーから『app→res→layout→activity_main.xml』を開いてください。

初期画面2

android_studio_kotlin電卓レイアウト1

右上にある『Design』タブを見つけてください。

android_studio_kotlin電卓レイアウト2

『Code』をクリックしてレイアウトをXML形式のコード表示にしてください。

android_studio_kotlin電卓レイアウト3

以下のコードをコピペしてください。右が切れていますので右上のアイコンをクリックしてコピーしてください。

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

<TextView
    android:id="@+id/result"
    android:layout_width="330dp"
    android:layout_height="90dp"
    android:layout_marginTop="140dp"
    android:text="0"
    android:textAlignment="viewEnd"
    android:textAppearance="@style/TextAppearance.AppCompat.Display1"
    android:textSize="60sp"
    app:layout_constraintEnd_toEndOf="parent"
    app:layout_constraintHorizontal_bias="0.493"
    app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintTop_toTopOf="parent" />

<Button
    android:id="@+id/eight"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_marginStart="2dp"
    android:layout_marginTop="60dp"
    android:layout_marginEnd="2dp"
    android:layout_marginBottom="2dp"
    android:text="8"
    android:textSize="24sp"
    app:layout_constraintBottom_toTopOf="@+id/five"
    app:layout_constraintEnd_toStartOf="@+id/nine"
    app:layout_constraintStart_toEndOf="@+id/seven"
    app:layout_constraintTop_toBottomOf="@+id/result" />

<Button
    android:id="@+id/two"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_marginStart="2dp"
    android:layout_marginTop="2dp"
    android:layout_marginEnd="2dp"
    android:layout_marginBottom="2dp"
    android:text="2"
    android:textSize="24sp"
    app:layout_constraintBottom_toTopOf="@+id/zero"
    app:layout_constraintEnd_toStartOf="@+id/three"
    app:layout_constraintStart_toEndOf="@+id/one"
    app:layout_constraintTop_toBottomOf="@+id/five" />

<Button
    android:id="@+id/six"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_marginStart="2dp"
    android:layout_marginTop="2dp"
    android:layout_marginEnd="2dp"
    android:layout_marginBottom="2dp"
    android:text="6"
    android:textSize="24sp"
    app:layout_constraintBottom_toTopOf="@+id/three"
    app:layout_constraintEnd_toStartOf="@+id/mul"
    app:layout_constraintStart_toEndOf="@+id/five"
    app:layout_constraintTop_toBottomOf="@+id/nine" />

<Button
    android:id="@+id/zero"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_marginStart="2dp"
    android:layout_marginTop="2dp"
    android:layout_marginEnd="2dp"
    android:text="0"
    android:textSize="24sp"
    app:layout_constraintEnd_toStartOf="@+id/equal"
    app:layout_constraintStart_toEndOf="@+id/ac"
    app:layout_constraintTop_toBottomOf="@+id/two" />

<Button
    android:id="@+id/four"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_marginStart="10dp"
    android:layout_marginTop="2dp"
    android:layout_marginEnd="2dp"
    android:layout_marginBottom="2dp"
    android:text="4"
    android:textSize="24sp"
    app:layout_constraintBottom_toTopOf="@+id/one"
    app:layout_constraintEnd_toStartOf="@+id/five"
    app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintTop_toBottomOf="@+id/seven" />

<Button
    android:id="@+id/nine"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_marginStart="2dp"
    android:layout_marginTop="60dp"
    android:layout_marginEnd="2dp"
    android:layout_marginBottom="2dp"
    android:text="9"
    android:textSize="24sp"
    app:layout_constraintBottom_toTopOf="@+id/six"
    app:layout_constraintEnd_toStartOf="@+id/div"
    app:layout_constraintStart_toEndOf="@+id/eight"
    app:layout_constraintTop_toBottomOf="@+id/result" />

<Button
    android:id="@+id/one"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_marginStart="10dp"
    android:layout_marginTop="2dp"
    android:layout_marginEnd="2dp"
    android:layout_marginBottom="2dp"
    android:text="1"
    android:textSize="24sp"
    app:layout_constraintBottom_toTopOf="@+id/ac"
    app:layout_constraintEnd_toStartOf="@+id/two"
    app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintTop_toBottomOf="@+id/four" />

<Button
    android:id="@+id/three"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_marginStart="2dp"
    android:layout_marginTop="2dp"
    android:layout_marginEnd="2dp"
    android:layout_marginBottom="2dp"
    android:text="3"
    android:textSize="24sp"
    app:layout_constraintBottom_toTopOf="@+id/equal"
    app:layout_constraintEnd_toStartOf="@+id/sub"
    app:layout_constraintStart_toEndOf="@+id/two"
    app:layout_constraintTop_toBottomOf="@+id/six" />

<Button
    android:id="@+id/seven"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_marginStart="10dp"
    android:layout_marginTop="60dp"
    android:layout_marginEnd="2dp"
    android:layout_marginBottom="2dp"
    android:text="7"
    android:textSize="24sp"
    app:layout_constraintBottom_toTopOf="@+id/four"
    app:layout_constraintEnd_toStartOf="@+id/eight"
    app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintTop_toBottomOf="@+id/result" />

<Button
    android:id="@+id/five"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_marginStart="2dp"
    android:layout_marginEnd="2dp"
    android:layout_marginBottom="2dp"
    android:text="5"
    android:textSize="24sp"
    app:layout_constraintBottom_toTopOf="@+id/two"
    app:layout_constraintEnd_toStartOf="@+id/six"
    app:layout_constraintStart_toEndOf="@+id/four"
    app:layout_constraintTop_toBottomOf="@+id/eight" />

<Button
    android:id="@+id/ac"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_marginStart="10dp"
    android:layout_marginTop="2dp"
    android:layout_marginEnd="2dp"
    android:text="AC"
    android:textSize="24sp"
    app:layout_constraintEnd_toStartOf="@+id/zero"
    app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintTop_toBottomOf="@+id/one" />

<Button
    android:id="@+id/equal"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_marginStart="2dp"
    android:layout_marginTop="2dp"
    android:layout_marginEnd="2dp"
    android:text="="
    android:textSize="24sp"
    app:layout_constraintEnd_toStartOf="@+id/add"
    app:layout_constraintStart_toEndOf="@+id/zero"
    app:layout_constraintTop_toBottomOf="@+id/three" />

<Button
    android:id="@+id/div"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_marginStart="2dp"
    android:layout_marginTop="60dp"
    android:layout_marginEnd="10dp"
    android:layout_marginBottom="2dp"
    android:text="÷"
    android:textSize="24sp"
    app:layout_constraintBottom_toTopOf="@+id/mul"
    app:layout_constraintEnd_toEndOf="parent"
    app:layout_constraintStart_toEndOf="@+id/nine"
    app:layout_constraintTop_toBottomOf="@+id/result" />

<Button
    android:id="@+id/mul"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_marginStart="2dp"
    android:layout_marginTop="2dp"
    android:layout_marginEnd="10dp"
    android:layout_marginBottom="2dp"
    android:text="×"
    android:textSize="24sp"
    app:layout_constraintBottom_toTopOf="@+id/sub"
    app:layout_constraintEnd_toEndOf="parent"
    app:layout_constraintStart_toEndOf="@+id/six"
    app:layout_constraintTop_toBottomOf="@+id/div" />

<Button
    android:id="@+id/sub"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_marginStart="2dp"
    android:layout_marginTop="2dp"
    android:layout_marginEnd="10dp"
    android:layout_marginBottom="2dp"
    android:text="-"
    android:textSize="24sp"
    app:layout_constraintBottom_toTopOf="@+id/add"
    app:layout_constraintEnd_toEndOf="parent"
    app:layout_constraintStart_toEndOf="@+id/three"
    app:layout_constraintTop_toBottomOf="@+id/mul" />

<Button
    android:id="@+id/add"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_marginStart="2dp"
    android:layout_marginTop="2dp"
    android:layout_marginEnd="10dp"
    android:text="+"
    android:textSize="24sp"
    app:layout_constraintEnd_toEndOf="parent"
    app:layout_constraintStart_toEndOf="@+id/equal"
    app:layout_constraintTop_toBottomOf="@+id/sub" />

</androidx.constraintlayout.widget.ConstraintLayout>

『Design』に切り替えて次の画像のようになっていれば完了です。

Kotlinのコードを入力

最初に起動される『MainActivity.kt』にKotlinの以下のコードをコピペしてください。閉じてしまった場合は『app→java→com.example.myapplication→MainActivity.kt』に保管されています。

android_studio_kotlinのコード

package com.example.myapplication

import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.widget.Button
import android.widget.TextView

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

//変数の宣言

        //数値を保持する変数の宣言
        var value : Int = 0

        //AC(All Clear)のフラグ
        var ac : Boolean = false

        //演算子を押した後に数字を押すなど計算を行うかを判断するフラグ
        var calc : Boolean = false

        //実行予定の演算子を保持しておく変数
        var operator : String = "no"    //演算子を未選択状態

        //ボタンの宣言
        val btnZero : Button = findViewById(R.id.zero)
        val btnOne  : Button = findViewById(R.id.one)
        val btnTwo  : Button = findViewById(R.id.two)
        val btnThree: Button = findViewById(R.id.three)
        val btnFour : Button = findViewById(R.id.four)
        val btnFive : Button = findViewById(R.id.five)
        val btnSix  : Button = findViewById(R.id.six)
        val btnSeven: Button = findViewById(R.id.seven)
        val btnEight: Button = findViewById(R.id.eight)
        val btnNine : Button = findViewById(R.id.nine)
        val btnAdd  : Button = findViewById(R.id.add)   // +
        val btnMul  : Button = findViewById(R.id.mul)   // -
        val btnSub  : Button = findViewById(R.id.sub)   // ×
        val btnDiv  : Button = findViewById(R.id.div)   // ÷
        val btnEqual:Button = findViewById(R.id.equal)  // =
        val btnAc : Button = findViewById(R.id.ac)      // AC

        //計算結果の表示
        val resultView : TextView = findViewById(R.id.result)


//関数の宣言

        //数字ボタンを押した時の関数
        fun numBtnAction(num : String) {
            resultView.text = if(resultView.text.toString() != "0" && ac == false){
                resultView.text.toString() + num
            } else {
                ac = false
                num
            }
            calc = true
        }

        //計算を実行する際の演算子を確認する
        fun calculation(op : String) :Int {
            return if (op == "+") {
                value + resultView.text.toString().toInt()
            } else if (op == "-") {
                value - resultView.text.toString().toInt()
            } else if (op == "*") {
                value * resultView.text.toString().toInt()
            } else if (op == "/") {
                value / resultView.text.toString().toInt()
            } else {
                resultView.text.toString().toInt()
            }
        }

        //計算の行う時の処理
        fun calcBtnAction(op : String) {
            if (calc) {     //calc == true
                value = calculation(operator)
                ac = true
                calc = false
                resultView.text = value.toString()
            }
            operator = op
        }

        //イコールボタンを押した時の関数
        fun equalBtnAction() {
            if (calc) {     //calc == true
                value = calculation(operator)
                calc = false
                ac = true
                resultView.text = value.toString()
                operator = "no"         //演算子を未選択
            }
        }

        //ACを押した時の関数
        fun acBtnAction(){
            resultView.text ="0"
            value = 0
            operator = "no"             //演算子を未選択
            ac = false
            calc = false
        }

//ボタンが押されたことを検知する処理

        //0
        btnZero.setOnClickListener {
            numBtnAction("0");
        }

        //1
        btnOne.setOnClickListener {
            numBtnAction("1");
        }

        //2
        btnTwo.setOnClickListener {
            numBtnAction("2");
        }

        //3
        btnThree.setOnClickListener {
            numBtnAction("3");
        }

        //4
        btnFour.setOnClickListener {
            numBtnAction("4");
        }

        //5
        btnFive.setOnClickListener {
            numBtnAction("5");
        }

        //6
        btnSix.setOnClickListener {
            numBtnAction("6");
        }

        //7
        btnSeven.setOnClickListener {
            numBtnAction("7");
        }

        //8
        btnEight.setOnClickListener {
            numBtnAction("8");
        }

        //9
        btnNine.setOnClickListener {
            numBtnAction("9");
        }

        //+
        btnAdd.setOnClickListener {
            calcBtnAction("+")
        }

        //-
        btnSub.setOnClickListener {
            calcBtnAction("-")
        }

        //×
        btnMul.setOnClickListener {
            calcBtnAction("*")
        }

        //÷
        btnDiv.setOnClickListener {
            calcBtnAction("/")
        }

        //=
        btnEqual.setOnClickListener {
            equalBtnAction()
        }

        //AC
        btnAc.setOnClickListener {
            acBtnAction()
        }
    }
}

Android端末での実機テスト

Google USB Driverのインストール

Tools→SDK Managerをクリックします。

GoogleUSBDriver1

左のタブで『Android SDK』を選択し、『SDK Tools』を選択。その中から『Google USB Driver』にチェックをして右下の『Apply』をクリックします。規約などが表示されますので、流れにそって進めていきます。

GoogleUSBDriver2

インストールが始まります。終わったら『Finish』をクリックします。

GoogleUSBDriver3

Google USB Driverが『Installed』になっていれば、ドライバーのインストールは完了です。

GoogleUSBDriver4

Android端末のセットアップ

今回は、HUAWEIの『honor9』という機種を使用します。画面の細部が異なる場合もありますが、基本的には同じ流れでセットアップできます。

設定→システム→端末情報に進みます

android端末のセットアップ1

android端末のセットアップ2

android端末のセットアップ3

『ビルド番号』を7回タップしてください。開発者向けの操作が可能になります。

android端末のセットアップ4

android端末のセットアップ5

設定→システム→開発者向けオプションと進み、『開発者向けオプション』がONになっていることを確認してください。実機でのテストが完了したら最後はOFFに戻しておくことをおすすめします。

android端末のセットアップ6


開発者向けオプション内にある『USBデバッグ』をONにします

android端末のセットアップ7

パソコンとAndroid端末をUSBで接続して、成功するとAndroid Studioの右上にAndroid端末の型式が表示されます。『▶』をクリックするとAndroid端末にアプリがインストールされて実機で確認することができます。

実機テスト1

実機でアプリの動作

※画像が古いので近日差し替えます

接続がうまく行かない時は、接続時のAndroid端末が確認してくる
・充電のみ / 写真 / ファイル転送
これで『ファイル転送』を選択してください。

エミュレータでアプリの動作を確認

エミュレータはかなり重いのでパソコンのスペックによっては、スムーズに動作しないことがあります。その場合は、Android端末で動作を確認することをおすすめします。

エミュレータのセットアップ

右上に表示されている『No Devices』をクリックして、表示される『Device Maneger』を選択します。

android_studio_kotlin電卓6

android_studio_kotlin電卓7

『Create device』をクリックします。

android_studio_kotlin電卓8

このAndroid Studio上でシミュレーションするデバイス(エミュレータ)を選択します。お好みですが、とりあえず左の『Phone』のタブから『Pixel 5』を選択して『Next』をクリックします。

android_studio_kotlin電卓9

そのままデフォルトのままで『Finish』まで進んで完了です。

android_studio_kotlin電卓10

右上にある『▶』か、もしくは『Run→Run ‘app’』をクリックします。パソコンのスペックによっては起動に時間がかかる場合があります。

android_studio_kotlin電卓12

エミュレータが起動して電卓アプリの動作を確認することができます。

android電卓レイアウト2

ボタンの色を変更したい時

アプリのボタンの色がデフォルトは紫なので、グレーに変更します。以下の2つのファイルを開きます。

・app→res→values→colors.xml
・app→res→values→themes→themes.xml

android電卓色の変更1

『colors.xml』に以下をコピペします。追加したのは10行目のGREYです。

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <color name="purple_200">#FFBB86FC</color>
    <color name="purple_500">#FF6200EE</color>
    <color name="purple_700">#FF3700B3</color>
    <color name="teal_200">#FF03DAC5</color>
    <color name="teal_700">#FF018786</color>
    <color name="black">#FF000000</color>
    <color name="white">#FFFFFFFF</color>
    <color name="GREY">#FF666666</color>
</resources>

『themes.xml』に以下をコピペします。変更したのは5行目です。

<resources xmlns:tools="http://schemas.android.com/tools">
    <!-- Base application theme. -->
    <style name="Theme.MyApplication" parent="Theme.MaterialComponents.DayNight.DarkActionBar">
        <!-- Primary brand color. -->
        <item name="colorPrimary">@color/GREY</item>
        <item name="colorPrimaryVariant">@color/purple_700</item>
        <item name="colorOnPrimary">@color/white</item>
        <!-- Secondary brand color. -->
        <item name="colorSecondary">@color/teal_200</item>
        <item name="colorSecondaryVariant">@color/teal_700</item>
        <item name="colorOnSecondary">@color/black</item>
        <!-- Status bar color. -->
        <item name="android:statusBarColor" tools:targetApi="l">?attr/colorPrimaryVariant</item>
        <!-- Customize your theme here. -->
    </style>
</resources>

落ち着いた雰囲気のボタンに変更することができました。

android電卓完成イメージ

うまし
うまし

ブログやサイトでご紹介、拡散してもらえるとはげみになります!