初めてのAndroidアプリ開発(Kotlin編)- プログラミングの基本 その2
東北TECH道場の参加者向けに作成したkotlinハンズオンのその2です。
その1はこちら
睡眠導入アプリの続き
引き続き睡眠誘導アプリを作っていきます、
これまでは画面に表示するのは文字だけでしたが、画像を表示したり音を出すようにしてみます。
(絵:デザイナー ナナ)
画像を表示してみましょう
画像ファイルのダウンロード
ここからダウンロードします
https://goo.gl/1kYJmW
zipを展開すると、中に2つの画像ファイルが入っています。
画像ファイルをプロジェクトに登録する
Android Studio
drawableの下にコピーします。
activity_main.xml に ImageView を追加して src に画像を指定します。
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.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:id="@+id/rootLayout"
tools:context="org.tohokutechdojo.test.sleeping.MainActivity">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello World!" />
<ImageView
android:id="@+id/imageView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/sheep_1" />
</android.support.constraint.ConstraintLayout>
実行して画像が表示されることを確認してみましょう
TextViewとImageView
TextView...文字を表示するための部品
ImageView ... 画像を表示するための部品
アニメーション
ダウンロードした画像は2枚でした。
この2枚の画像をタップする度に切り替えてアニメーションしているようにしてみます。
class MainActivity : AppCompatActivity() {
var sheepCount = 0
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
var greeting = "こんにちは"
val trialTime = Date()
val calendar = GregorianCalendar()
calendar.time = trialTime
val hour = calendar.get(Calendar.HOUR_OF_DAY)
if (hour in 1..11) {
greeting = "おはよう"
} else if (hour > 15) {
greeting = "こんばんは"
}
greeting += "ねむれませんか?"
textview.text = greeting
rootLayout.setOnClickListener {
sheepCount++
val sheepText = "ひつじが$sheepCount 匹"
textview.text = sheepText
when(sheepCount % 2) {
0 -> imageView1.setImageResource(R.drawable.sheep_1) // 追加
else -> imageView1.setImageResource(R.drawable.sheep_2) // 追加
}
}
}
}
実行してみましょう
画面をタップすると数字が増えると同時に2枚の絵が交互に表示されて、羊が歩いているように見えると思います。
ソースコードの説明
when(sheepCount % 2) {
0 -> imageView1.setImageResource(R.drawable.sheep_1) // 追加
else -> imageView1.setImageResource(R.drawable.sheep_2) // 追加
}
sheepCount % 2
は羊を数えた回数を2で割った余りを求めています。
0 ->
で余りが0(偶数)の時、else ->
で余りが0以外(奇数)の時となり、偶数の時は1枚めの羊の絵(sheep_1)、奇数の時は2枚めの羊の絵(sheep_2)をimageView1にセットして表示を切り替えています。
音を出してみましょう
音声ファイルをダウンロードします。
https://goo.gl/b37aEp
ダウンロードしたらzipファイルを解凍しておきます。
音声ファイルを組み込む
プロジェクトファイルに音声ファイルを組み込みます。
res で右クリック ⇒ New ⇒ Android Resource Directory と辿ります。
開いたダイアログで、Resource Type から raw を選択してrawという名前のフォルダを作成します。
この raw の中に音声ファイルを入れます。
MainActivity.ktを次のように修正します。
class MainActivity : AppCompatActivity() {
var sheepCount = 0
var mp: MediaPlayer? = null // 追加
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
var greeting = "こんにちは"
val trialTime = Date()
val calendar = GregorianCalendar()
calendar.time = trialTime
val hour = calendar.get(Calendar.HOUR_OF_DAY)
if (hour in 1..11) {
greeting = "おはよう"
} else if (hour > 15) {
greeting = "こんばんは"
}
greeting += "ねむれませんか?"
textview.text = greeting
mp = MediaPlayer.create(applicationContext, R.raw.sheep_cry1) // 追加
rootLayout.setOnClickListener {
sheepCount++
val sheepText = "ひつじが$sheepCount 匹"
textview.text = sheepText
when(sheepCount % 2) {
0 -> { // 追加
imageView1.setImageResource(R.drawable.sheep_1) // 追加
mp?.start() // 追加
}
else -> imageView1.setImageResource(R.drawable.sheep_2)
}
}
}
}
実行してみましょう
画面をタップすると「めぇ~」と羊の鳴き声の音が出るはずです。
(音が聞こえない時は端末のボリュームを確認してみてください)
ソースコードの説明
var mp: MediaPlayer? = null
Androidで音声ファイルを再生する方法は幾つかありますが、ここではMediaPlayerというクラス(部品)を使います。
この行ではMediaPlayerのオブジェクトを保持するための変数を定義しています。
変数の型の後ろに?を付けて MediaPlayer?
としている理由は、
?を付けることでnull許容型(nullを代入できる型)として宣言をし、nullを代入するためです。
?を付けずにnullを代入しようとすると、Kotlinではエラーになります。
mp = MediaPlayer.create(applicationContext, R.raw.sheep_cry1)
res/rawの下に登録した音声ファイル(sheep_cry1)を使ってMediaPlayerのオブジェクトを生成します。これ以降、このmpを使って再生のコントロールができるようになります。
mp?.start();
MediaPlayerのオブジェクトのstart()という命令(メソッドと呼びます)を呼び出すことで音声の再生を開始します。
mpの後ろに?を付けてmp?
とすることで、mpがnullで無ければmp.start()
を実行するという意味になります。
ちなみにこれをJavaに書き換えると、
if (mp != null) {
mp.start()
}
となります。