カテゴリー
Kotlin言語

ゼロから始めるAndroidアプリ(Kotlin編)Unit1 – 4 第2回:ボタンに処理を記述する

Android Developers > スタートガイド > Kotlin と Android をゼロから学ぶ > Unit1 – Kotlin を用いた Android の基本Unit1-4 第2回 の内容をまとめたものです(翻訳ではありません)。また、一部関連した内容を追加しました


Unit1 – 4 の 第2回

第2回の内容は以下の通りです

  • 第1回のKotlinコード(乱数を発生させる)を組み込んだAndroidアプリを作ります
  • ボタンを押したら結果がテキストで表示されるようにします
  • アプリのUI画面は Android Studio の Layout Editor で作成し、ボタンを押したときの動作は Kotlin で記述します

具体的には次のようなレッスンです

  • activity_main.xml を開いてアプリに Button(ボタンの View )を追加します
  • MainActivity.kt を開いて Button をタップしたときの動作を記述します
  • Toast(Androidのポップアップメッセージ)を使います
  • アプリからKotlinコードで TextView を書き換えます

Layout Editor でUI画面を作成する

まず Layout Editor を使ってアプリの画面を作成してみますね

  • Android Studio で新規にプロジェクトを作成します
    • アプリの名前(Name)は “Dice Roller”
    • 使用言語(Language)は Kotlin
    • APIレベル(Minimum SDK)は 19 (KitKat)
    • テンプレートは Empty Activity
  • Project で activity_main.xml (app > res > layout > activity_main.xml) をダブルクリックすると Layout Editor が開きます
  • あらかじめ “Hello World” を表示する TextView が作られているので、その下に Pallet から Button をドロップします。これらの View 部品は ConstraintLayoutViewGroup にあるレイアウトのひとつ)に配置されます
  • ViewGroup に配置された View は親子関係( ViewGroup が親、View が子)にあります

つづいて ButtonTextView の配置やスタイルを修正するんですね

うん、constraint(制約)が大切なの。かならず縦方向、横方向それぞれに設定してね

  • Button の配置とスタイルを修正
    • Design viewButton に constraint(制約)を設定します
    • Button に表示されるテキスト(text)を “Roll” に変更します
    • Component TreeButton にあるオレンジのをクリックして Fix ボタンを押します。ハードコードされている文字列を、文字列リソース strings.xml を使うように修正します
  • TextView のスタイルを修正
    • Design viewTextView を選択して、Attributes にある textSize を 36sp に変更します
    • Attributes Common Attributes セクションにある text 項目を空に、ツールアイコン(スパナ)のついた text に 1 を設定します
    • ツールアイコンのついた text 項目(tools text)は Android Studio の Design view でのみ text の代わりに表示されます。UIデザイン作成中の表示サンプルです

Activity の理解と import の自動化

Android の画面は Activity として管理されているんですね

  • Android Studio でプロジェクトを作成するとまず MainActivity という Activity が最初に作成されます
  • MainActivity を開く・・・Project MainActivity.kt ファイルを開く (app > java > com.example.diceroller > MainActivity.kt)
package com.example.diceroller

import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle

class MainActivity : AppCompatActivity() {

   override fun onCreate(savedInstanceState: Bundle?) {
       super.onCreate(savedInstanceState)
       setContentView(R.layout.activity_main)
   }
}
  • Kotlinは通常 main() から処理を始めます。しかし Android の Kotlin は MainActivity の onCreate() メソッドから処理を始めるようになっています

Android Studio を使うとKotlinコードへの import の記述を自動化できます

  • 表示されたソースコードで import ... となっている部分は ... をクリックして展開(表示)できます
  • Androidには膨大なクラスが用意されていて、これらを使ってアプリを作成します
    • クラスを使うには import を使ってクラスのある場所をあらかじめ特定しておく必要があります
    • たとえば Button があるのは android.widget.Button なので、これを import で宣言しておきます
  • 使用するクラスがどこにあるか把握して、それをいちいち import 宣言して書いておくのは大変な作業です
  • Android Studio には、書いているプログラムで使っているクラスを判別して import 宣言の内容を自動で書き換えてくれる機能があります。使わなくなったクラスの import 宣言を自動で削除することも可能です

import の自動設定を有効にしますね

  1. Android Studio で Preferences for New Projects を開きます(File > New Project Settings > Preferences for New Projects
  2. 開いたウィンドウで Other Settings > Auto Import と展開します
  3. Java セクション と Kotlin セクションにある Add unambiguous imports on the fly(追加機能)と Optimize imports on the fly (for current project)(削除機能)にチェックを入れます
  4. OK ボタンを押す

自動 import がうまく動作しなかったときはクラス名が赤で反転表示されます。クラス名の上にカーソルを移動して Alt+Enter で修正してくださいね

ボタンに機能を割り当てる

ボタンをクリックすると Toast がポップアップするアプリを作成しますね

class MainActivity : AppCompatActivity() {

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

       val rollButton: Button = findViewById(R.id.button)
       rollButton.setOnClickListener {
           val toast = Toast.makeText(this, "Dice Rolled!", Toast.LENGTH_SHORT)
           toast.show()
       }
   }
}

ボタンを作成してKotlinで扱えるようにします

  • Layout EditorButton を作成し、これに button というID(リソースID)を付けます
  • Button につけられた button というリソースIDは、Kotlinプログラムから R.id.button として参照できます
  • findViewById(R.id.button) は、Kotlinプログラムが R.id.button というリソースIDを持つオブジェクトへアクセスするための参照を返します
  • val rollButton: Button = findViewById(R.id.button) ・・・Button型の変数 rollButton にオブジェクトへの参照を代入します。rollButton をインスタンスとしてUIの button を操作できるようになります

ボタンに click listener を設定します

  • ボタンがクリックされたことを検知する機能は click listener です
  • click listener を、クリックされたことを検知したい View 部品に設定します
    • 部品のオブジェクト.setOnClickListener { 処理内容 }
    • setOnClickListener を使って、ボタンがクリックされたことを検知するとともに、そのときに行う処理を書いておくことができます

Toast でメッセージ表示ですね

  • val toast = Toast.makeText(this, "Dice Rolled!", Toast.LENGTH_SHORT) ・・・toast オブジェクトの作成
  • toast.show() ・・・toast の表示をします
  • Toast.makeText(this, "Dice Rolled!", Toast.LENGTH_SHORT).show() ・・・変数を使わずにインスタンスの生成と表示をまとめることもできます

Toast のかわりに TextView で表示するにはこんな感じですね

class MainActivity : AppCompatActivity() {

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

       val rollButton: Button = findViewById(R.id.button)
       rollButton.setOnClickListener {
           val resultTextView: TextView = findViewById(R.id.textView)
           resultTextView.text = "6"
       }
   }
}
  • Layout Editor を使って activity_main.xmlTextView を作成し、リソースIDを textView と設定します
  • MainActivity.ktfindViewByID(R.id.textView) を使って textView への参照を記述します
  • インスタンスの text プロパティに値を設定します
    • このプログラムでは常に 6 を表示しています

KotlinコードでView部品を操作するには、 findViewById のかわりに View Binding を使うのがおすすめなんですね

  • このチュートリアルの解説は findViewByID を使ったものなんですが、将来的には findViewByID は View Binding に置き換わるそうです
  • View Binding を使うことで findViewByID を使わずにView部品へ簡単にアクセスできるようになります
  • View Binding を使うには、Android Studio 3.6 以降(できれば 4.0 以降)を使います
  • 詳しくは以下にまとめました

乱数を表示する

まず Dice クラスを作成してみますね

class MainActivity : AppCompatActivity() {

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

       val rollButton: Button = findViewById(R.id.button)
       rollButton.setOnClickListener {
           val resultTextView: TextView = findViewById(R.id.textView)
           resultTextView.text = "6"
       }
   }
}

class Dice(val numSides: Int) {

   fun roll(): Int {
       return (1..numSides).random()
   }

}
  • Diceクラスのコードを追加します
  • Android Studio上で、Diceクラスの numSides がグレーに反転しているとおもいます。カーソルをのせると private にしたほうがいいかもとアドバイスが出ます。ダイアログの Make ‘numSides’ ‘private’ をクリックして private に修正しておきます

つぎは setOnClickListener の中身の書き換えですね

class MainActivity : AppCompatActivity() {

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

       val rollButton: Button = findViewById(R.id.button)
       rollButton.setOnClickListener {
           rollDice()
       }
   }
}

class Dice(val numSides: Int) {

   fun roll(): Int {
       return (1..numSides).random()
   }

}
  • setOnClickListener の内容を rollDice() に変更します
  • すると警告が出る(出ないときは rollDice の上で Alt+Enter)ので More action… を選択します
  • リストが出るので Create function ‘rollDice()’ を選択
  • MainActivity クラスの中に rollDice 関数のひな型が作られます

rollDice 関数のひな型が追加されるとこんな感じです

class MainActivity : AppCompatActivity() {

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

       val rollButton: Button = findViewById(R.id.button)
       rollButton.setOnClickListener {
           rollDice()
       }
   }

    private fun rollDice() {
        TODO("Not yet implemented")
    }

}

class Dice(val numSides: Int) {

   fun roll(): Int {
       return (1..numSides).random()
   }

}

rollDice 関数の内容を記述します

今回はこれで完成ですね

class MainActivity : AppCompatActivity() {

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

       val rollButton: Button = findViewById(R.id.button)
       rollButton.setOnClickListener {
           rollDice()
       }
   }

    private fun rollDice() {
        val dice = Dice(6)
        val diceRoll = dice.roll()
        val resultTextView: TextView = findViewById(R.id.textView)
        resultTextView.text = diceRoll.toString()
    }

}

class Dice(val numSides: Int) {

   fun roll(): Int {
       return (1..numSides).random()
   }

}

見やすいコードの書き方

  • Kotlinスタイルガイドを参考にします
  • Android Studio にソースコードを自動で見やすく整形する機能があります
    1. MainActivity.kt を開いてすべてを選択(Ctrl+a)
    2. Code > Reformat Code を実行
  • 行をまとめてコンパクトにすると見やすくなります
  • ちゃんとコメントを入れる( /* ~ */ , /** ~ */ , //)

この回のまとめ

  • Androidアプリに Button を追加するには Layout Editor を使います
  • アプリに機能を加えたいときは MainActivity.kt に記述されたクラスを修正します
  • ちょっとした動作確認をするのに Toast は便利
  • ボタンをクリックしたときの動作は setOnClickListener() メソッドを使ってボタンに追加します
  • アプリ実行時の画面更新は、レイアウトに使われている View 部品のプロパティやメソッドを利用して行います
  • ソースコードは見やすく、コメントもちゃんと入れるとお行儀がいいです