はじめに

今回の勉強会は最終回、ロジック実装の後編です。

今回の勉強会が一通り実践できるようになると、下記のようなことができるようになります!

  • 条件分岐を含んだロジックを実装できるようになる
  • onCreateメソッドを理解することができる
  • クラスの継承、メソッドのオーバーライドを理解できるようになる

今回のキーポイント

  • 条件分岐
  • Androidアプリにおけるライフサイクル
  • クラスの継承とメソッドのオーバーライド

前回の勉強会で基本的な文法を学び、「入力フォームに文字を入れてボタンを押したら、下部に文字が表示される」という機能を実装しました。
今回の勉強会ではクリアボタンを機能、下部の文字表示と入力フォームを空にする機能を実装しましょう!

前回の内容はこちら

前回作成したアプリを開こう!

今回も、前回のアプリを引き続き使用します。

AndroidStudioのWelcome画面から前回作成したアプリ(DisplayProfile)を選択してエディタを開きましょう。

今回のゴール

今回のゴールは前回お見せしたものと同じです。前回は途中までで終わりましたが、今回は以下のファイルを完全に実装するところまで進めます!

MainActivity.kt

package com.example.displayprofile

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

class MainActivity : AppCompatActivity(), View.OnClickListener {

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

        val btDisplay = findViewById<Button>(R.id.btDisplay)
        btDisplay.setOnClickListener(this)
        val btClear = findViewById<Button>(R.id.btClear)
        btClear.setOnClickListener(this)

    }

    override fun onClick(v: View) {
        val tvDisplayName = findViewById<TextView>(R.id.tvDisplayName)
        val tvDisplayFrom = findViewById<TextView>(R.id.tvDisplayFrom)
        val tvDisplayLanguage = findViewById<TextView>(R.id.tvDisplayLanguage)
        val etName = findViewById<EditText>(R.id.etName)
        val etFrom = findViewById<EditText>(R.id.etFrom)
        val etLanguage = findViewById<EditText>(R.id.etLanguage)
        when (v.id){
            R.id.btDisplay -> {
                tvDisplayName.text = "氏名:" + etName.text
                tvDisplayFrom.text = "出身:" + etFrom.text
                tvDisplayLanguage.text = "学習中の言語:" + etLanguage.text
            }
            R.id.btClear -> {
                etName.setText("")
                etFrom.setText("")
                etLanguage.setText("")
                tvDisplayName.text = ""
                tvDisplayFrom.text = ""
                tvDisplayLanguage.text = ""
            }
        }   
    }
}

前回までで実装した部分

MainActivity.kt

上記に載せたコードが今回のゴールですが、前回はこのMainActivity.ktの途中まで実装しました。その状態のコードを以下に記載します。第3回をまだ進めていない方は、このコードをMainActivity.ktにコピペしてから、今回の勉強会を進めていきましょう。

package com.example.displayprofile

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

class MainActivity : AppCompatActivity(), View.OnClickListener {

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

        val btDisplay = findViewById<Button>(R.id.btDisplay)
        btDisplay.setOnClickListener(this)

    }

    override fun onClick(v: View?) {
        val tvDisplayName = findViewById<TextView>(R.id.tvDisplayName)
        val tvDisplayFrom = findViewById<TextView>(R.id.tvDisplayFrom)
        val tvDisplayLanguage = findViewById<TextView>(R.id.tvDisplayLanguage)
        val etName = findViewById<EditText>(R.id.etName)
        val etFrom = findViewById<EditText>(R.id.etFrom)
        val etLanguage = findViewById<EditText>(R.id.etLanguage)
        tvDisplayName.text = "氏名:" + etName.text
        tvDisplayFrom.text = "出身:" + etFrom.text
        tvDisplayLanguage.text = "学習中の言語:" + etLanguage.text
    }
}

クリアボタン処理の実装

クリアボタンにもリスナーを付けよう

今回のメインとなる作業は、クリアボタンを押した時の処理を追加することです。
前回のやり方と同じ手順で進めます。まずはボタンにリスナーを付けるところから始めましょう。

onCreateメソッドの中、btDisplayにリスナーを設定した文の下に、以下の2文を記述します。

        val btDisplay = findViewById<Button>(R.id.btDisplay)
        btDisplay.setOnClickListener(this)
        // ↓こちらを新たに記述
        val btClear = findViewById<Button>(R.id.btClear)
        btClear.setOnClickListener(this)

前回と全く同じ書き方なので、どのような意味の文かは想像できるかと思います。

「型がButton, 名前がbtClearのインスタンスを作り、XMLファイルで定義したbtClearという画面部品とインスタンスを結びつける」

という意味です。XMLファイルで定義たbtClearは、クリアボタンのことです。

前回実装した箇所の変更

次に、onClickメソッドにクリアボタンの処理を追加していくのですが、変更する箇所が一点あります。

onClickメソッドの引数vの型をView? と指定していますが、

override fun onClick(v: View?) {

こちらを以下のように変更してください。

override fun onClick(v: View) {

View?のままでも実装できるのですが、onClick内に書く文が若干変わります。今回は簡易的なやり方で実装します。
このあたりについて気になる方は、「Kotlin Nullable null回避」で調べてみてください。

文字を空にする

これから、onClickメソッド内に条件分岐を追加します。やりたいことは、

表示ボタンを押した場合:文字が表示される
クリアボタンを押した場合:表示している文字を空に、入力フォームも空にする

という機能でした。条件分岐よりも文字を空にするやり方のほうが簡単なので、先にそれを紹介します。

tvDisplayName.text = "氏名:" + etName.text // tvDisplayNameに文字列を入れる(前回の作業)
tvDisplayName.text = "" // tvDisplaynameに空文字を入れる = 文字を空にする

ラベルの文字を空にするのは非常に簡単です。前回の作業でラベルに文字を定義しましたが、今回はラベルに空文字を定義すればラベルが空になります。

入力フォームについては、setTextというメソッドを使う必要があります。

etName.setText("") // 入力フォーム(EditText型のオブジェクトについては、setTextメソッドを使う)

以上より

etName.setText("")
etFrom.setText("")
etLanguage.setText("")
tvDisplayName.text = ""
tvDisplayFrom.text = ""
tvDisplayLanguage.text = ""

と書くことで、ラベルと入力フォームの文字が全て空になることがわかります。

条件分岐 when の導入

つづいて、条件分岐を実装します。

条件分岐は大きく分けてif文とwhen文の2つがありますが、今回はwhen文を使います。

Kotlinにおけるwhen文の使い方は以下のとおりです。

when(条件式){
    A -> {
        Aのときやりたいこと
    }
    B -> {
        Bのときやりたいこと
    }
    else -> {
        その他の場合やりたいこと
    }
}

このような形で書きます。今回は、その他の場合にやりたいことはありません。その他の部分を省略し、やりたいことを当てはめると以下のようになります。

when(押すボタン){
    表示ボタン -> {
        tvDisplayName.text = "氏名:" + etName.text
        tvDisplayFrom.text = "出身:" + etFrom.text
        tvDisplayLanguage.text = "学習中の言語:" + etLanguage.text
    }
    クリアボタン -> {
        etName.setText("")
        etFrom.setText("")
        etLanguage.setText("")
        tvDisplayName.text = ""
        tvDisplayFrom.text = ""
        tvDisplayLanguage.text = ""
    }
}

ゴールが見えてまいりました。あとは、条件式を正しく記述するだけです。

「どのボタンを押したか」という条件式

今回やりたいことをふまえると、「どのボタンを押したか」という条件をKotlinで表現すればいいということになります。

ここで、onClickメソッドの段落の最初の文を見てみましょう。

override fun onClick(v: View)

onClickは、setOnClickListenterを定義したボタンがクリックされると自動的に実行されるメソッドのことでした。このことから、onClickメソッドの引数(v: View)は、

クリックしたViewクラスのインスタンス(このメソッド内では仮にvと名付ける)

という意味だということがわかります。
※Viewクラスは、TextViewクラスやEdittextクラス、Buttonクラスの継承元(親のようなもの)です。

setOnClickListenerを定義したインスタンスは、

  • btDisplay (表示ボタンのインスタンス)
  • btClear (クリアボタンのインスタンス)

の2つでした。つまり、

「クリックしたインスタンスvがdbDisplayなのか、それともdbClearなのか」

という条件式で今回の条件分岐を表すことができます。これをコードで表現すると、

when (v.id){
    R.id.btDisplay -> {
        tvDisplayName.text = "氏名:" + etName.text
        tvDisplayFrom.text = "出身:" + etFrom.text
        tvDisplayLanguage.text = "学習中の言語:" + etLanguage.text
    }
    R.id.btClear -> {
        etName.setText("")
        etFrom.setText("")
        etLanguage.setText("")
        tvDisplayName.text = ""
        tvDisplayFrom.text = ""
        tvDisplayLanguage.text = ""
    }
}  

このようになります。インスタンスそのものではなく、インスタンスのidを用いて条件分岐を実装しています。

ついに今回の勉強会のゴール、サンプルアプリが完成しました!!

※インスタンスそのもの、つまり、when(v){ という書き方も可能です。その場合、R.id.btDisplayを修正する必要があるのですが、どのような書き方をすればいいでしょうか。R.id. をただ除くだけではうまくいきません。この課題にも是非チャレンジしてみてください!

アプリを動かしてみよう

最後の確認として、アプリを動かしてみましょう。下図のように、文字を入力して表示ボタンを押してから、クリアボタンを押してみましょう。クリアボタンを押してすべての表示が消えたら成功です。

これ以降は、今までで説明を省いていたところを補足していきます。

Androidアプリにおけるライフサイクル

MainActivityの上部に、onCreateというメソッドがあります。これはAndroidプロジェクトを作成する際に自動的に作られたものですが、このonCreateは、

アプリ画面が開いたときに、中に書かれていることを実行する

という役割を持っています。

Androidにはこれに似たメソッドが揃っており、多くのアプリではそれらが有効活用されています。
このメソッドをさらに深く理解するために重要な概念である、アプリ画面のライフサイクルについて紹介します。

ライフサイクルとは

Androidのスマホの画面は1つしか表示することができません。しかし、アプリを複数開きっぱなしにすることはできます(皆さまのスマホも、アプリが複数起動している状態になっているかと思います)。

つまり、「画面が開いている」ことと「画面が見えている」ことは違う、ということです。

画面が見える、アプリは起動中だが画面は見えない等の、アプリは様々な画面状態があります。そして、画面の状態が変化するタイミングで自動的に働く機能を実装することができます。
この概念のことを、ライフサイクルと呼びます。

このうち、画面が新たに生成され表示されるタイミングで実行されるメソッドがonCreateメソッドです。

この他にもonStartメソッドやonResumeメソッド、onDestroyメソッドなどがあります。
詳細は以下のリンクをご覧ください。こちらのサイトは、Android開発元が発信している、公式リファレンス(いわゆる一次情報)です。AndroidStudioをダウンロードしたのもこのサイトでしたね。

https://developer.android.com/guide/components/activities/activity-lifecycle#alc

クラスの継承とメソッドのオーバーライド

※こちらの解説は、別資料を用いて解説いたします。
 当学園内で以前Ruby入門書の輪読会を実施しており、そこで使われたクラスの解説スライドを使用します。
 こちらに記事化するまでは、お手数ですが対応する解説動画を御覧ください。

エミュレータで日本語を入力できるようにしよう

エミュレータを使用するにあたっての前提

この章では、エミュレータ(PC上で動くダミースマホ)の設定についてご説明します。この勉強会に参加されている方のほとんどは、アプリの動作を確かめる際にこのエミュレータを使われているかと思います。

しかし、多くのAndroid開発現場では、動作確認の際はエミュレータではなくAndroid端末実機を使用します。
アプリ開発のゴールは「お客様に、自身のスマホで利用していただくこと」なので、実機で動作確認をするのは自然な考えですよね。

一方個人開発レベルになると、実機を用意できないことの方が多いかと思います。
もともとAndroidスマホをお持ちならそれを使えばいいのですが、動作確認をするためだけに実機を購入するのは気が引けてしまいますよね。

したがって、「エミュレータは、実機をお持ちでない方のための仮のスマホ」という認識でいてください。今回は言語設定という最低限の設定をエミュレータでいたしますが、「実際の現場では実機を使うことが多いからエミュレータの細かい設定はあまり知らなくても大丈夫」ということを頭に入れておいてください。

エミュレータの日本語入力

※第1回で紹介した、Nexud5Xをもとにご説明します。

エミュレータを起動したら、設定(Setting)を開きます。下部真ん中のホームボタンを上にドラッグすると以下の画面が出てくるので、そこから選択しましょう。

そこから、System -> Languages & input -> Languages と選択し、言語設定を開きます。

現状だと、上図のように英語のみが選択されているかと思います。
その下のAdd a language を押し、日本語 を選択します。リストをスクロールし、一番下に日本語の選択肢があります。

English, 日本語と並んで表示されたら、右端の = のような記号をドラッグし、日本語を一番上に移動させます。

これにより、エミュレータの第一言語が日本語になります。以下のように言語が自動的に変わるはずです。

次に、キーボード設定を行います。

一つ前の設定に戻ると上図のような画面になります。画面キーボード -> Gboard -> 言語 と選択していきます。

この画面から、「キーボードを追加」ボタンを押します。
先ほどと同じように言語の一覧が出てくるので、そこから日本語を選択してください。

QWERTYが選択されていることを確認し、完了ボタンを押します。

以上の操作で、日本語入力の設定が完了しました。

おわりに

今回は、Androidアプリのロジック実装を行いました。

条件分岐の実装や、前回説明を省いたところを学ぶことができました。

全4回を通して、Androidアプリ開発大まかな流れを理解することができ、最低限の専門用語もある程度理解する事ができたかと思います。

ここまでできたら、「Androidアプリを開発した経験があります!」と自信をもって言ってしまいましょう!!
見た目を整えることができ、ボタンのクリック処理まで実装できたので、れっきとしたAndroidアプリ開発者の仲間入りです!

ここで学んだことをもとに、さらに発展的なアプリ開発を進めていただければと思います。

今回の勉強会はここまでです。お疲れさまでした!

この記事が気に入ったら
フォローしよう

最新情報をお届けします

Twitterでフォローしよう

おすすめの記事