#1.今回のテーマ
前回まで3回にわたって画面レイアウトについて解説してきました。
今回からはいよいよ(?)処理の実装編に入ります。
android studioから新規プロジェクトを作成すると、
・activity_main.xlm:
・MainActivity.kt(言語としてkotlinを選択した場合)
の2つが作成されます。
「.xml」ファイルで画面レイアウトを定義し、それに対応する処理を「.kt」に書いていきます。
.xmlファイルのことを「レイアウトファイル」
.ktファイルのことを「アクティビティ」
と呼びます。
android開発では、このように画面レイアウトを定義するレイアウトファイルと、その画面での処理を実装するアクティビティがセットになっています。
では今回のテーマです。
まずはトップ画面に実装した処理から解説していきます。
今回の音符フラッシュカードアプリで実装した画面は3つ。
このように1つのアプリで複数画面がある場合、画面間でデータを受け渡す必要性が出てくると思います。
今回はトップ画面で選択したレベルを次のゲーム画面に引き渡すところまでを解説していきたいと思います。
#2.ボタンの定義を再確認
「ト音初級」ボタンを例にとって書いていきます。
xmlは以下の通りです。
<ImageButton
android:id="@+id/bt_right_biginer"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="32dp"
android:tag="ト音初級"
app:srcCompat="@drawable/right_biginer" />
処理を実装する上で重要なのは
android:id="@+id/bt_right_biginer"
android:tag="ト音初級"
の2つです。
#3.onCreate()メソッドについて
android studioからプロジェクトを作成した時点で、.ktファイルにはonCreateメソッドが自動で記載されます。
package com.websarva.wings.android.musicnotecardquiz
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
}
}
onCreateは、このアクティビティが呼び出された時点で実行されるメソッドです。
そのため、画面作成やデータの用意など、初期処理として必要なものはこのメソッド内に書く必要があります。
メソッドの中にはあらかじめ2行が記載されています。
super.onCreate(savedInstanceState)
⇒これは、親クラスのonCreate()メソッドを呼び出しています。
アクティビティクラスはActicityクラスを継承して作成する必要があります。
onCreate()メソッドは親クラスであるActivityクラスで定義されているメソッドで、それをオーバーライドする形で記述します。
その際、親クラスであるActivityクラスのonCreate()メソッドも処理しておく必要があるため、この記述が必要なのです。
と、いろいろと書きましたがandroid studioがデフォルトで準備してくれる記述のままで問題ありませんので、そういうものだと思っていただければとりあえずはよいかと思います。
setContentView(R.layout.activity_main)
⇒こちらは、このアクティビティで表示する画面を設定しています。今回はactivity_main.xlmに記述したものを画面として使うので、引数を「R.layout.activity_main」としています。
次に、R.という記述について解説します。
Android開発では、resフォルダ内のファイルやそのファイル内に書かれた「@+id」等の値にプログラムから容易にアクセスできるように、Rクラスというものが用意されています。
main_activity.xml内で、「ト音初級」ボタンに「id」を定義しましたが、そうするとAndroid Studioが自動的にRクラスに定義値を追記してくれます。
以降、
R.id.bt_right_biginer
と記述することで、このボタンを呼び出すことができるようになります。
onCreate()メソッド内に自動で記載された
「R.layout.activity_main」は「res/layout/activity_main.xml」ファイルを指す定数です。
#4.「ト音初級」ボタンが押された時の処理
それでは「ト音初級」ボタンが押された時の処理をMainActivity.ktに実装していきます。
実装する内容を簡単に説明すると以下の通りです。
(1)「ト音初級」ボタンが押されたことを検知する
(2)「ト音初級」ボタンの定義から、tagに書かれた文字列を取得する
(3)取得したtagを次の画面に渡すための変数にセットする
(4)次の画面を起動する
androidでは、ボタンをタップ、アイコンをドラッグなど、ユーザが画面に愛して何らかの操作を行うことを「イベント」と呼びます。
そのイベントに対応して行う処理のことを「イベントハンドラ」、イベントの検出を行っているものを「リスナ」と呼びます。
上記の(1)~(4)のうち、(1)はリスナ、(2)~(4)はイベントハンドラで実装していきます。
では、
(1)「ト音初級」ボタンが押されたことを検知する
処理を書いていきます。
まず最初に、「ト音初級」ボタンオブジェクトを取得します。
私はこの「オブジェクトを取得する」という概念が今一つわかりませんでしたが、次のように考えると良いと思います。
処理を書いていく際は、どの画面部品に対する処理なのかを意識して書くことが多いと思います。
例えば今回のように、
・あるボタンを押したら、何らかの動作をする
という場合もあるでしょうし、
・プログラムで編集した文字列を、ある特定のテキストビューにセットする
あるいは、
・あるプルダウンリストで選択した値に応じて、データベースからデータを取得する
こともあると思います。
上の例で太字にした部分は、画面のどの部品のことを指しているのか、プログラムに書いてあげないと適切な処理が実装できません。この、画面のどの部品のことを指しているのかを示してあげることが「オブジェクトを取得する」ということです。
なんとなくイメージが付いたでしょうか。
画面の部品を取得するには、
findViewById()
メソッドを使います。
名前の通り、idによってViewを見つける、というメソッドです。
実際のコードを見ていきましょう。
val btRightBiginer = findViewById<ImageButton>(R.id.bt_right_biginer)
findViewById直後の<>内には、取得したい部品の型を記述します。
今回の「ト音初級ボタン」は、以下の通りImageButton型でしたので、それを記述します。
<ImageButton
android:id="@+id/bt_right_biginer"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="32dp"
android:tag="ト音初級"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toEndOf="@+id/bt_left_biginer"
app:layout_constraintTop_toBottomOf="@+id/time_third"
app:srcCompat="@drawable/right_biginer" />
そして<>の後の()内には、同じくxmlで定義したidの値を書きます。
画面定義の記事で、あとで処理を実装するときに使う、と書きましたが、ようやくここで出番が来ました。
本記事の最初でR値についての説明をしましたが、ここでもR値で書いていきます。
「ト音初級ボタン」は「bt_right_biginer」というidで定義したので、
R.id.bt_right_biginer
と記述することで、ト音初級ボタンという部品が取得できます。
左辺の
val btRightBiginer =
は、以降このメソッド内では「ト音初級」ボタンはbtRightBiginerという変数で扱うことを宣言しています。
ボタン内の他の属性にアクセスする際は、このbtRightBiginerという変数を使います。
例えば、ト音初級ボタンのtagにセットする文字列を変えたい場合は
btRightBiginer.tag="XXXXXX"
と記述します。
次に、リスナクラスのインスタンスを生成します。
val listener1 = StartButtonClickListener()
**StartButtonClickListener()**というのが、リスナクラスに当たります。
このリスナクラス内にイベントハンドラを記述していきます。
この時点ではStartButtonClickListener()というクラスは実装されていないため、エラーになります。この後実装するので問題ありません。
最後に「ト音初級」ボタンに対してリスナを設定します。
btRightBiginer.setOnClickListener(listener1)
リスナの設定は、実装するイベントによって変わりますが、今回はボタンをクリックしたことを検知するリスナなので、**setOnClickListener()**というメソッドを使ってリスナを設定します。
以上で「ト音初級ボタンに対するリスナ設定が完了しました。
ソースコードとしてはたったの3行です。
3行まとめて以下に記載しておきます。
//レベル選択ボタンを取得
val btRightBiginer = findViewById<ImageButton>(R.id.bt_right_biginer)
//リスナクラスを生成
val listener1 = StartButtonClickListener()
//レベル選択ボタンに対してリスナーセット
btRightBiginer.setOnClickListener(listener1)
続いてリスナクラス**StartButtonClickListener()**と、その中にイベントハンドラを実装していきます。
実装したい処理は、以下の3つです。
(2)「ト音初級」ボタンの定義から、tagに書かれた文字列を取得する
(3)取得したtagを次の画面に渡すための変数にセットする
(4)次の画面を起動する
まずはリスナクラスを宣言します。
private inner class StartButtonClickListener : View.OnClickListener {
override fun onClick(view: View) {
}
}
クリック(タップ)というイベントに対するリスナクラスを作成するには、View.OnClickListenerインターフェースを実装します。
private inner class StartButtonClickListener : View.OnClickListener
インターフェースを実装した時点でそのインターフェースに定義されているメソッドを記述する必要があります。View.OnClickListenerインターフェースではonClick()メソッドがそれに当たります。
このonClick()こそが、イベントハンドラであり、ここに処理を記述するのが次の手順になります。
override fun onClick(view: View) {
}
それではonClick()メソッドの記述を見ていきましょう。
override fun onClick(view: View) {
//ゲーム画面へのインテントを準備・・・①
val intent2Game = Intent(this@MainActivity, GameActivity::class.java)
//押されたレベルボタンからタグを取得して、インテントにセット・・・②
val level = view.tag.toString()
intent2Game.putExtra("level", level)
//ゲーム画面に遷移(渡すのはレベルのみ)・・・③
startActivity(intent2Game)
}
androidにおける画面遷移の中心となるクラスがIntentです。
このクラスが、画面(=アクティビティ)の起動をつかさどります。
具体的には、以下の手順を踏みます。
①Intentクラスのインスタンスを生成する。
②起動先アクティビティに渡すデータを格納する。
③アクティビティを起動する。
先ほどのソースコード内に①~③で対応を記載しています。
①Intentクラスのインスタンスを生成する。
val intent2Game = Intent(this@MainActivity, GameActivity::class.java)
intent2Gameは任意の変数名です。今回はゲーム画面への遷移ということで、この名前を付けました。
Intentクラスのインスタンスを生成するには2つの引数が必要です。
第1引数:PackageContext: Context
画面遷移をする元となるアクティビティ(=自分自身)です。
this@MainActivityを設定します。
第2引数:cls: Class
遷移先のアクティビティをJavaクラス化したものです。kotlinのクラスをJavaクラス化したものを指定する場合は、「クラス名::class.java」と記述します。
通常、kotlinでクラスそのものを表す場合は「クラス名::class」と記述します。
一方で、kotlinはJVM上で動作する言語なので、Javaのオブジェクトと簡単にやり取りができるようになっています。
そして、Intentクラスのコンストラクタの第2引数はkotlinのクラスではなくJavaのクラスを渡す仕様になっています。そこで、kotlin内でJavaのクラスを表す表記である「クラス名::class.java」を使うことでkotlinのクラスをJavaのクラスとして渡しているのです。
言語の仕様としては上記の通りですが、あまり難しく考えずに「起動先のアクティビティの名前::class.java」と書くものだと覚えれば問題ないと思います。
第1引数がfrom、第2引数がtoのアクティビティを指すと考えるとイメージがわきやすいと思います。
②起動先アクティビティに渡すデータを格納する。
//押されたレベルボタンからタグを取得して、インテントにセット・・・②
val level = view.tag.toString()
intent2Game.putExtra("level", level)
1行目の記述から解説します。
viewという変数が登場していますが、このviewは、onClick()メソッドの引数として渡される画面部品のことを指します。
override fun onClick(view: View) {
}
「ト音初級」ボタンが押された際に呼ばれる場合は、viewには「ト音初級」ボタンが格納されています。
従って、findViewByIdメソッドを使って改めてビューを取得する必要はありません。
val level = view.tag.toString()
という記述で、「ト音初級」ボタンのtagの値を文字列型にキャストしてlevelという変数に格納しています。
tagは
android:tag="ト音初級"
と、もとから文字列型で定義されていましたが、明示的にtoString()で文字列型にキャストしています。
その上で、putExtra()メソッドを使って次の画面に渡すデータとしてIntentクラスのインスタンスにセットしていきます。
intent2Game.putExtra("level", level)
putExtra()メソッドでは、第1引数にデータの名称、第2引数にデータそのものを記述します。levelという変数に格納したview.tagのデータを"level"という名前で次の画面に引き継ぎます、という意味です。
遷移先の画面では、この"level"という名前を使ってデータを取得します。
どうでしょう。
別画面にデータを渡す方法がわかりましたでしょうか。
#5.「ト音初級」以外のボタンが押された時の処理
「ト音初級」以外のボタンが押された時の処理ですが、「ト音初級」ボタンが押された時の処理とやりたいことはまったく一緒です。
(1)ボタンが押されたことを検知する
(2)ボタンの定義から、tagに書かれた文字列を取得する
(3)取得したtagを次の画面に渡すための変数にセットする
(4)次の画面を起動する
もう一度イベントハンドラを見てみましょう。
override fun onClick(view: View) {
//ゲーム画面へのインテントを準備・・・①
val intent2Game = Intent(this@MainActivity, GameActivity::class.java)
//押されたレベルボタンからタグを取得して、インテントにセット・・・②
val level = view.tag.toString()
intent2Game.putExtra("level", level)
//ゲーム画面に遷移(渡すのはレベルのみ)・・・③
startActivity(intent2Game)
}
変数viewにはクリックされたボタンが設定されるので、上記のコードは何も変えることなく使えます。なので、あとはonCreate()メソッド内で、それぞれのボタンに対してリスナーを設定してあげるだけで良いです。
//レベル選択ボタンを取得
val btRightBiginer = findViewById<ImageButton>(R.id.bt_right_biginer)
val btRightMiddle = findViewById<ImageButton>(R.id.bt_right_middle)
val btRightHigh = findViewById<ImageButton>(R.id.bt_right_high)
val btLeftBiginer = findViewById<ImageButton>(R.id.bt_left_biginer)
val btLeftMiddle = findViewById<ImageButton>(R.id.bt_left_middle)
val btLeftHigh = findViewById<ImageButton>(R.id.bt_left_high)
val btBothBiginer = findViewById<ImageButton>(R.id.bt_both_biginer)
val btBothMiddle = findViewById<ImageButton>(R.id.bt_both_middle)
val btBothHigh = findViewById<ImageButton>(R.id.bt_both_high)
//レベル選択ボタンリスナー
val listener1 = StartButtonClickListener()
//リスナーセット
btRightBiginer.setOnClickListener(listener1)
btRightMiddle.setOnClickListener(listener1)
btRightHigh.setOnClickListener(listener1)
btLeftBiginer.setOnClickListener(listener1)
btLeftMiddle.setOnClickListener(listener1)
btLeftHigh.setOnClickListener(listener1)
btBothBiginer.setOnClickListener(listener1)
btBothMiddle.setOnClickListener(listener1)
btBothHigh.setOnClickListener(listener1)
「ト音初級」ボタンと同様に、
・リスナを設定するボタンをfindViewById()で取得する
・setOnClickListenerを設定する
という処理を各ボタンに対して実装してあげればよいだけです。
StartButtonClickListenerクラスのonClick()メソッドはそのまま共通的に使えます。
最後に今回の説明に関連するソースコードを載せておきます。
<?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"
android:background="@color/white"
tools:context=".MainActivity">
<TextView
android:id="@+id/label_ranking"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:text="@string/label_ranking"
android:textSize="24dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/label_rank"
android:layout_width="36dp"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginTop="8dp"
android:text="@string/label_rank"
android:textSize="18dp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/sp_selectLevel" />
<TextView
android:id="@+id/label_name"
android:layout_width="100dp"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginTop="8dp"
android:text="@string/label_name"
android:textSize="18dp"
app:layout_constraintStart_toEndOf="@+id/label_rank"
app:layout_constraintTop_toBottomOf="@+id/sp_selectLevel" />
<TextView
android:id="@+id/label_time"
android:layout_width="64dp"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginTop="8dp"
android:text="@string/label_time"
android:textSize="18dp"
app:layout_constraintStart_toEndOf="@+id/label_name"
app:layout_constraintTop_toBottomOf="@+id/sp_selectLevel" />
<TextView
android:id="@+id/label_correct_count"
android:layout_width="44dp"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginTop="8dp"
android:text="@string/label_correct_count"
android:textSize="18dp"
app:layout_constraintStart_toEndOf="@+id/label_time"
app:layout_constraintTop_toBottomOf="@+id/sp_selectLevel" />
<TextView
android:id="@+id/label_date"
android:layout_width="108dp"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginTop="8dp"
android:text="@string/label_date"
android:textSize="18dp"
app:layout_constraintStart_toEndOf="@+id/label_correct_count"
app:layout_constraintTop_toBottomOf="@+id/sp_selectLevel" />
<TextView
android:id="@+id/rank_first"
android:layout_width="36dp"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginTop="8dp"
android:text="@string/label_rank_first"
android:textSize="18dp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/label_rank" />
<TextView
android:id="@+id/name_first"
android:layout_width="100dp"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginTop="8dp"
android:text="-"
android:textSize="18dp"
app:layout_constraintStart_toEndOf="@+id/rank_first"
app:layout_constraintTop_toBottomOf="@+id/label_name" />
<TextView
android:id="@+id/time_first"
android:layout_width="64dp"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginTop="8dp"
android:text="-"
android:textSize="18dp"
app:layout_constraintStart_toEndOf="@+id/name_first"
app:layout_constraintTop_toBottomOf="@+id/label_time" />
<TextView
android:id="@+id/correct_count_first"
android:layout_width="44dp"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginTop="8dp"
android:text="-"
android:textSize="18dp"
app:layout_constraintStart_toEndOf="@+id/time_first"
app:layout_constraintTop_toBottomOf="@+id/label_correct_count" />
<TextView
android:id="@+id/date_first"
android:layout_width="108dp"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginTop="8dp"
android:text="-"
android:textSize="18dp"
app:layout_constraintStart_toEndOf="@+id/correct_count_first"
app:layout_constraintTop_toBottomOf="@+id/label_date" />
<TextView
android:id="@+id/rank_second"
android:layout_width="36dp"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginTop="8dp"
android:text="@string/label_rank_second"
android:textSize="18dp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/rank_first" />
<TextView
android:id="@+id/name_second"
android:layout_width="100dp"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginTop="8dp"
android:text="-"
android:textSize="18dp"
app:layout_constraintStart_toEndOf="@+id/rank_second"
app:layout_constraintTop_toBottomOf="@+id/name_first" />
<TextView
android:id="@+id/time_second"
android:layout_width="64dp"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginTop="8dp"
android:text="-"
android:textSize="18dp"
app:layout_constraintStart_toEndOf="@+id/name_second"
app:layout_constraintTop_toBottomOf="@+id/time_first" />
<TextView
android:id="@+id/correct_count_second"
android:layout_width="44dp"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginTop="8dp"
android:text="-"
android:textSize="18dp"
app:layout_constraintStart_toEndOf="@+id/time_second"
app:layout_constraintTop_toBottomOf="@+id/correct_count_first" />
<TextView
android:id="@+id/date_second"
android:layout_width="108dp"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginTop="8dp"
android:text="-"
android:textSize="18dp"
app:layout_constraintStart_toEndOf="@+id/correct_count_second"
app:layout_constraintTop_toBottomOf="@+id/date_first" />
<TextView
android:id="@+id/rank_third"
android:layout_width="36dp"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginTop="8dp"
android:text="@string/label_rank_third"
android:textSize="18dp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/rank_second" />
<TextView
android:id="@+id/name_third"
android:layout_width="100dp"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginTop="8dp"
android:text="-"
android:textSize="18dp"
app:layout_constraintStart_toEndOf="@+id/rank_third"
app:layout_constraintTop_toBottomOf="@+id/name_second" />
<TextView
android:id="@+id/time_third"
android:layout_width="64dp"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginTop="8dp"
android:text="-"
android:textSize="18dp"
app:layout_constraintStart_toEndOf="@+id/name_third"
app:layout_constraintTop_toBottomOf="@+id/time_second" />
<TextView
android:id="@+id/correct_count_third"
android:layout_width="44dp"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginTop="8dp"
android:text="-"
android:textSize="18dp"
app:layout_constraintStart_toEndOf="@+id/time_third"
app:layout_constraintTop_toBottomOf="@+id/correct_count_second" />
<TextView
android:id="@+id/date_third"
android:layout_width="108dp"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginTop="8dp"
android:text="-"
android:textSize="18dp"
app:layout_constraintStart_toEndOf="@+id/correct_count_third"
app:layout_constraintTop_toBottomOf="@+id/date_second" />
<Spinner
android:id="@+id/sp_selectLevel"
android:entries="@array/levelList"
android:layout_width="128dp"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginTop="8dp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/label_ranking" />
<ImageButton
android:id="@+id/bt_right_biginer"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="32dp"
android:tag="ト音初級"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toEndOf="@+id/bt_left_biginer"
app:layout_constraintTop_toBottomOf="@+id/time_third"
app:srcCompat="@drawable/right_biginer" />
<ImageButton
android:id="@+id/bt_right_high"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:tag="ト音上級"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toEndOf="@+id/bt_left_high"
app:layout_constraintTop_toBottomOf="@+id/bt_right_middle"
app:srcCompat="@drawable/right_high" />
<ImageButton
android:id="@+id/bt_right_middle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:tag="ト音中級"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toEndOf="@+id/bt_left_middle"
app:layout_constraintTop_toBottomOf="@+id/bt_right_biginer"
app:srcCompat="@drawable/right_middle" />
<ImageButton
android:id="@+id/bt_left_biginer"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="32dp"
android:tag="へ音初級"
app:layout_constraintEnd_toStartOf="@+id/bt_right_biginer"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/time_third"
app:srcCompat="@drawable/left_biginer" />
<ImageButton
android:id="@+id/bt_left_middle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:tag="へ音中級"
app:layout_constraintEnd_toStartOf="@+id/bt_right_middle"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/bt_left_biginer"
app:srcCompat="@drawable/left_middle" />
<ImageButton
android:id="@+id/bt_left_high"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:tag="へ音上級"
app:layout_constraintEnd_toStartOf="@+id/bt_right_high"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/bt_left_middle"
app:srcCompat="@drawable/left_high" />
<ImageButton
android:id="@+id/bt_both_biginer"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:tag="両手初級"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/bt_left_high"
app:srcCompat="@drawable/both_biginer" />
<ImageButton
android:id="@+id/bt_both_middle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:tag="両手中級"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/bt_both_biginer"
app:srcCompat="@drawable/both_middle" />
<ImageButton
android:id="@+id/bt_both_high"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:tag="両手上級"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/bt_both_middle"
app:srcCompat="@drawable/both_high" />
</androidx.constraintlayout.widget.ConstraintLayout>
package com.websarva.wings.android.musicnotecardquiz
import android.content.Intent
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.view.View
import android.widget.*
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
//レベル選択ボタンを取得
val btRightBiginer = findViewById<ImageButton>(R.id.bt_right_biginer)
val btRightMiddle = findViewById<ImageButton>(R.id.bt_right_middle)
val btRightHigh = findViewById<ImageButton>(R.id.bt_right_high)
val btLeftBiginer = findViewById<ImageButton>(R.id.bt_left_biginer)
val btLeftMiddle = findViewById<ImageButton>(R.id.bt_left_middle)
val btLeftHigh = findViewById<ImageButton>(R.id.bt_left_high)
val btBothBiginer = findViewById<ImageButton>(R.id.bt_both_biginer)
val btBothMiddle = findViewById<ImageButton>(R.id.bt_both_middle)
val btBothHigh = findViewById<ImageButton>(R.id.bt_both_high)
//レベル選択ボタンリスナー
val listener1 = StartButtonClickListener()
//リスナーセット
btRightBiginer.setOnClickListener(listener1)
btRightMiddle.setOnClickListener(listener1)
btRightHigh.setOnClickListener(listener1)
btLeftBiginer.setOnClickListener(listener1)
btLeftMiddle.setOnClickListener(listener1)
btLeftHigh.setOnClickListener(listener1)
btBothBiginer.setOnClickListener(listener1)
btBothMiddle.setOnClickListener(listener1)
btBothHigh.setOnClickListener(listener1)
}
private inner class StartButtonClickListener : View.OnClickListener {
override fun onClick(view: View) {
//ゲーム画面へのインテントを準備
val intent2Game = Intent(this@MainActivity, GameActivity::class.java)
//押されたレベルボタンからタグを取得して、インテントにセット
val level = view.tag.toString()
intent2Game.putExtra("level", level)
//ゲーム画面に遷移(渡すのはレベルのみ)
startActivity(intent2Game)
}
}
今回は以上です。また長文になってしまいました。
次回は、トップ画面から受け渡された値をゲーム画面で利用する方法について説明します。
①概要
②画面デザイン~トップ画面(Constraint Layout)~
③画面デザイン~ゲーム画面(Linear Layout)~
④画面デザイン~結果画面(Linear Layoutその2)~
⑤トップ画面からの遷移(インテント(putExtra))(本記事)
⑥トップ画面から引き継いだデータ表示(インテント(getExtra))
⑦問題出題(ロジック実装)
⑧回答ボタン押下(効果音再生(MediaPlayer、正誤判定、次の問題出題)
⑨タイムカウンターの実装(handler)
⑩ゲーム画面から引き継いだゲーム結果表示(インテント)
⑪当日日付データ取得
⑫DB保存(SQLite、Insert)
⑬もう一度、トップ画面へ戻るボタン(インテント)
⑭ランキング表示(SQLite、Select)
⑮実機でのテスト
⑯Google Playで公開