さいころアプリを作成する~さいころの画像を追加する~

2020/08/11

Android kotlin プログラミング

前回はif・else文について学び、ラッキーナンバーを設定できるようになりました。今回はさいころを振った結果によって表示されるさいころの画像を変えます。

(googleの無料講座の順に進んでいます。)

前回の記事とgoogleの講座はこちらです。
googleの講座
前回の記事
ちなみに今回がこの講座の最後です。

前回作ったアプリに画像を追加する

以前作成したさいころを振るアプリを元に改良をしていきます。

最初にactivity_main.xmlをクリックし、レイヤーエディタを開きます。(下記赤枠)
次にコンポーネントリストからテキストを削除します。(下記緑枠)
削除の方法は右クリック→Delete、もしくは選択した状態でDeleteキーを押してください。

次にROLLボタンの上に画像を追加します。
ここでは一旦avatarsを選択します。
画像の追加の仕方についてはこちらの記事を参考にしてください。

画像を追加した直後は"垂直方向の制約がない"という旨のエラーメッセージが出ています。
これはテキストボックスを削除したことで制約も削除されてしまったからです。制約の追加の仕方は先ほどのリンクに書いてあるので、ここでは省略します。画像の制約を次のように設定し、ボタンを画像に下に持ってきます。

講座には記載がなかった?ですが画像とROLLボタンは接続しています。
こうすることで画像を動かすとROLLボタンも一緒に動くようになります。

接続したうえでROLLボタンを画像の真下にもっていきます。
この状態でも警告文が出ていますが、一旦放置します。

さいころの画像をダウンロードする

まず最初にさいころの画像をダウンロードします。
下記リンクをクリックすることでさいころの画像が入ったzipがダウンロードされます。

zipファイルを解凍したら、アプリに画像を追加します。
まず初めにResource Managerを開きます。



先ほどダウンロードした画像を追加します。
画像はまとめて追加することができます。(Shift押しながら選択)

そのあとnext→importを押したら画像の追加は完了です。

ダウンロードしたさいころの画像を使用する

今アバター画像が表示されていますが、これをさいころの画像に変更します。
画像をクリックした状態でsrcCompatを選択し、さいころの画像にします。
今回は一の目のさいころを選択します。
ここで注意しなくてはいけないのはsrcComptで選んだ画像は開発中にしか表示されません。アプリを実行したときは表示されないので注意してください。

これでさいころの画像が追加されましたが、画像が大きすぎてROLLボタンが隠れてしまいました。

次に画像の大きさを小さくします。layout_widthとlayout_heightを次のように変更します。

これでボタンが見えるようになりました。

このままでもいいですが、さいころの画像とボタンの位置が近いので、ボタンを画像から離します。

これで画像の追加が完了しました。
次からはボタンが押された時に画像を変えるようにします。

ボタンが押されたときに表示される画像を変える

ボタンを押された時の挙動を変えるためにMainActivityウィンドウに切り替えます。

テキストボックスを削除したのにMainActivityでテキストボックスを使っているので、当たり前ですが現在のまま実行するとエラーが出ます。

MainActivity内の下記2行を削除します。
val resultTextView: TextView = findViewByID(R.id.textView)
resultTextView.text = dice.roll().toString()

代わりにimageView変数を作成します。
val diceImage: ImageView = findViewById(R.id.imageView)
一応画像のIDは下記で確認することができます。


diceImage変数にはさいころの目が2の時の画像を代入します。
これでボタンを押すと2の目の画像が表示されるようになります。

実際は2以外の画像も表示する必要がありますが、それは次にやっていきます。
diceImage.setImageResource(R.drawable.dice_2)
このコードを実行した結果がこちらです。

また、この時点でのrollDice関数は次のようになっていると思います。
private fun rollDice() {
val dice = Dice(6)
val diceRoll = dice.roll()
val diceImage: ImageView = findViewById(R.id.imageView)
diceImage.setImageResource(R.drawable.dice_2)
}

さいころを振った結果によって表示される画像を変更する

前回の記事で勉強したwhen文を使って、さいころの結果によって表示する画像を変えていきます。
diceImage.set。ImageResource(R.drawable.dice_2)のか所をwhen文を使って次のように変更します。
when (diceRoll) {
1 -> diceImage.setImageResource(R.drawable.dice_1)
2 -> diceImage.setImageResource(R.drawable.dice_2)
3 -> diceImage.setImageResource(R.drawable.dice_3)
4 -> diceImage.setImageResource(R.drawable.dice_4)
5 -> diceImage.setImageResource(R.drawable.dice_5)
6 -> diceImage.setImageResource(R.drawable.dice_6)
}

変更後のソースコートは次のようになっています。
private fun rollDice() {
val dice = Dice(6)
val diceRoll = dice.roll()
val diceImage: ImageView = findViewById(R.id.imageView)
when (diceRoll) {
1 -> diceImage.setImageResource(R.drawable.dice_1)
2 -> diceImage.setImageResource(R.drawable.dice_2)
3 -> diceImage.setImageResource(R.drawable.dice_3)
4 -> diceImage.setImageResource(R.drawable.dice_4)
5 -> diceImage.setImageResource(R.drawable.dice_5)
6 -> diceImage.setImageResource(R.drawable.dice_6)
}
}


これでROLLボタンを押したらさいころの目が変わるようになりました。

コードの最適化

このままでもいいですが、コードを短くしていきます。
画像イメージを格納する変数を追加して、さいころを振った結果によってこの変数に格納する画像を変えていきます。
val drawableResource = when (diceRoll) {
1 -> R.drawable.dice_1
2 -> R.drawable.dice_2
3 -> R.drawable.dice_3
4 -> R.drawable.dice_4
5 -> R.drawable.dice_5
6 -> R.drawable.dice_6
}
diceImage.setImageResource(drawableResource)
今回は大丈夫ですが、もしwhen文に赤い下線が表示されていたら、when文が網羅的に記述されていないことが原因だと考えられます。
例えば、さいころの面を12面に増やした場合はこのままでの記述では条件を満たさない場合が出てきてしまいます。

これを回避するためにAndroid Studioではelse文を記述することを提案しています。
val drawableResource = when (diceRoll) {
1 -> R.drawable.dice_1
2 -> R.drawable.dice_2
3 -> R.drawable.dice_3
4 -> R.drawable.dice_4
5 -> R.drawable.dice_5
else -> R.drawable.dice_6
}
diceImage.setImageResource(drawableResource)
このように記述することで、想定外の値が入った場合でも対処することができます。

説明にどの数字が出たかを追加する

これで数字によって表示されるさいころの画像が変更されるようにまりました。
画像では表示されるようになりましたが、どの数字が出たか文字として残すことができません。

ここではImageViewの説明欄にどの数字が出たかを格納します。
diceImage.contentDescription = diceRoll.toString()

(補足)多分これを記述することで、画像のパラメータの下記赤枠が更新されると思います。

アプリ起動時にさいころの画像を表示するようにする。

今のままだとボタンがクリックされたときにしかさいころの画像が表示されません。

起動直後に何も表示されないのは違和感があるので、起動時にもさいころを表示するようにします。
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val rollButton: Button = findViewById(R.id.button)
rollButton.setOnClickListener { rollDice() }
// 起動時にランダムなさいころを振って表示する
rollDice()
}

コメントを追加する

後から見てもわかるようにコードにコメントを追加していきます。
/**
* さいころを振って画面に結果を表示する
*/
private fun rollDice() {
// 6面のさいころを作成してさいころをふる
val dice = Dice(6)
val diceRoll = dice.roll()
// レイアウトからImage Viewを見つける
val diceImage: ImageView = findViewById(R.id.imageView)
// diceRoll変数に格納された値によってどの画像を変数に格納するか決める
val drawableResource = when (diceRoll) {
1 -> R.drawable.dice_1
2 -> R.drawable.dice_2
3 -> R.drawable.dice_3
4 -> R.drawable.dice_4
5 -> R.drawable.dice_5
else -> R.drawable.dice_6
}
//画像の更新
diceImage.setImageResource(drawableResource)
// Update the content description
diceImage.contentDescription = diceRoll.toString()
}

詳しく知りたい方へ



自己紹介

はじめまして 社会人になってからバイクやプログラミングなどを始めました。 プログラミングや整備の記事を書いていますが、独学なので間違った情報が多いかもしれません。 間違っている情報や改善点がありましたらコメントしていただけると幸いです。

X(旧Twitter)

フォローお願いします!

ブログ アーカイブ

QooQ