Pythonでブログ検索順位取得ツールを作るのが上手くいったし、次はゲームかなんか作ろうかな~
と、いい気になって考え出しました、まゆみです。
Pythonでゲームを作ることもできるようですが、
どうせなら、娘に遊んでもらえるようにアプリにしよう!
と考え付きまして、この度Andoroidアプリ開発を始めることにしました!
Andoroidアプリ開発といえば、Android Studioが必須。
以前、夫たんたんがMacにAndroid Studioを導入して記事にしていました。
が、私のPCはWindowsなので、Android Studioの導入や設定を以下の書籍を参考に行いました。
開発環境を以下にまとめておきます。
- windows10 64bit
- Intel Core i-5
- メモリ8GB
- Android Studio 3.4.2
- 言語:kotlin
- AVD(仮想端末):Nexus 5X , API level 27(←参考書籍で紹介されていたのを選んだ)
今回は、初心者が必ずと言ってもいいほど作るであろう、「ストップウォッチ」を作ってみました。
初めてのアプリ開発。
上手くいくのでしょうか・・・?
ストップウォッチアプリ作成:参考のソースをそのまま作ってみた結果
参考書籍の通りにAndroid Studioを設定し、「Hello World!」の表示まではすんなり終わりました。
何か作ってみたいと思い、以下の参考HPで紹介されていたストップウォッチアプリを作ってみることにしました。
以下のソースコードは、参考HPのをそのまま書き写したものです。
説明は参考HPでご覧ください。
写しただけで、自分でアレンジしてないので、すんなり実行できると思ったのですが、思わぬエラーが出てしまいました。
package com.example.myapplication
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.widget.Button
import android.widget.TextView
class MainActivity : AppCompatActivity() {
val handler = Handler() //一度だけ代入
var timeValue = 0 //何度も代入
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
/* テキストとボタンの変数定義 */
val timeText = findViewById(R.id.timeText) as TextView
val startButton = findViewById(R.id.startButton) as Button
val stopButton = findViewById(R.id.stopButton) as Button
val resetButton = findViewById(R.id.resetButton) as Button
/* 1秒ごとに処理を実行する */
val runnable = object : Runnable {
override fun run() {
timeValue++
// TextViewを更新
// ?.letを用いて、nullではない場合のみ更新
timeToText(timeValue)?.let{
// timeToText(timeValue)の値がlet内ではitとして使える
timeText.text = it
}
handler.postDelayed(this, 1000)
}
}
//startボタン機能
startButton.setOnClickListener{
handler.post(runnable)
}
//stopボタン機能
stopButton.setOnClickListener {
handler.removeCallbacks(runnable)
}
//resetボタン機能
resetButton.setOnClickListener {
handler.removeCallbacks(runnable)
timeValue = 0
// timeToTextの引数はデフォルト値が設定されているので、引数省略できる
timeToText()?.let {
timeText.text = it
}
}
}
// 数値を00:00:00形式の文字列に変換する関数
// 引数timeにはデフォルト値0を設定、返却する型はnullableなString?型
private fun timeToText(time: Int = 0): String? {
// if式は値を返すため、そのままreturnできる
return if (time < 0) {
null
} else if (time == 0) {
"00:00:00"
} else {
val h = time / 3600
val m = time % 3600 / 60
val s = time % 60
"%1$02d:%2$02d:%3$02d".format(h,m,s)
}
}
}
ビルドしたら1件エラーが出てしまいました。
10行目のHandlerの箇所でエラーになっています。
メッセージに出ている「Task:app:buildInfoGeneratorDebug」で検索しても、良い情報は出てこず・・・
しかし、「Unsolved reference」の方で検索してみたら解決しました。
エラー対応
ビルドエラー「 Unsolved reference : Handler 」の原因。
それは、
でした。
根本的なところ・・・
というわけで、以下の一文を追加
import android.os.Handler
するとビルドはエラーが無くなりうまくいきましたが、エミュレータに表示された画面がこちら↓
ボタンの位置がおかしい。
activity_main.xmlでボタンの位置を設定し直します。
どうも「STOP」と「RESET」の上側の余白の設定ができていなかったので、時刻表示のテキストからの幅を指定しました。
その際、ボタンの上側と時刻テキストの下側を矢印で繋げないと上手く設定できないので注意です。
ボタンの配置を再設定した後の実行画面はこちら↓
上手く配置できています。
完成したストップウォッチアプリ(1秒間隔)
作成したストップウォッチアプリの動作をGIF動画でご覧ください。
(たぶん)ちゃんと時間を計れています。
これで完成☆
ミリ秒に対応させよう
ストップウォッチアプリが動くところを見た夫たんたんが、
ミリ秒も表示してよ!
と言ってきました。
まぁ確かにストップウォッチと言えばミリ秒も表示されているなぁ。
ということで、ミリ秒も表示できるようにしてみました。
ソースコード
ミリ秒に対応させたソースコードはこちらです。
これ以外に、画面の時刻表示のデフォルトテキストを「00:00:00.00」に修正しました。
表示は10ミリ秒までの表示にしています。
package com.example.myapplication
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.widget.Button
import android.widget.TextView
import android.os.Handler
class MainActivity : AppCompatActivity() {
val handler = Handler() //一度だけ代入
var timeValue:Long = 0 //何度も代入
val interval:Long = 50 //msec
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
/* テキストとボタンの変数定義 */
val timeText = findViewById(R.id.timeText) as TextView
val startButton = findViewById(R.id.startButton) as Button
val stopButton = findViewById(R.id.stopButton) as Button
val resetButton = findViewById(R.id.resetButton) as Button
/* 1秒ごとに処理を実行する */
val runnable = object : Runnable {
override fun run() {
timeValue++
// TextViewを更新
// ?.letを用いて、nullではない場合のみ更新
timeToText(timeValue*interval)?.let{
// timeToText(timeValue)の値がlet内ではitとして使える
timeText.text = it
}
handler.postDelayed(this, interval)
}
}
//startボタン機能
startButton.setOnClickListener{
handler.post(runnable)
}
//stopボタン機能
stopButton.setOnClickListener {
handler.removeCallbacks(runnable)
}
//resetボタン機能
resetButton.setOnClickListener {
handler.removeCallbacks(runnable)
timeValue = 0
// timeToTextの引数はデフォルト値が設定されているので、引数省略できる
timeToText()?.let {
timeText.text = it
}
}
}
// 数値を00:00:00形式の文字列に変換する関数
// 引数timeにはデフォルト値0を設定、返却する型はnullableなString?型
private fun timeToText(time: Long = 0): String? {
// if式は値を返すため、そのままreturnできる
return if (time < 0) {
null
} else if (time.toInt() == 0) {
"00:00:00.00"
} else {
/* msec */
val h = time / 3600000
val m = (time % 3600000) / 60000
val s = ((time % 3600000) % 60000) / 1000
val ms = (time % 1000) / 10 //表示用にさらに10で割る
"%1$02d:%2$02d:%3$02d.%4$02d".format(h,m,s,ms)
}
}
}
1ms,10ms間隔だと、上手くいかなかった
実は、1ミリ秒間隔や10ミリ秒間隔で動作させてみると上手くいきませんでした。
むっちゃ遅いのです。
ストップウォッチの1秒が通常の3秒くらいになってしまいました。
CPUの問題なのか?何なのか?
ひとまず、50ミリ秒間隔でやってみたら、それなりに時間を計れるようになったので、これで良しとしました。
50ミリ秒間隔でカウントしたストップウォッチアプリの動作はこちらのGIF動画でごらんください↓。
アプリ開発もkotlinも初めてでしたが、HPを参考にしまくってストップウォッチアプリを作ることができました。
あまり理解できてないけど(汗)
参考書籍やHPなどでもっとアプリ制作を学んで、オリジナルのアプリを作ってみたいです。
今思い描いているのは、娘向けの知育ゲームアプリ。
Androidアプリ開発/kotlinの勉強の様子を、また記事にまとめていきます。
んじゃ、また~
おススメのプログラミング独学方法はこちらの記事にまとめました!
コメント