androidとkotlinの入門　ストップウォッチ


kotlinでアンドロイドのソフト開発を始めたばかりの素人です  

なので、間違いを堂々を書いている可能性があります
先にあやまっておきます
「ごめんなさい」

  
普段は[他のブログ](https://folivoradesu.blogspot.com/)で、ひっそりと試行錯誤の備忘録を書いています。　　
誰も来ません！　　
備忘録なので、いいと思ってなのですが、独学なので間違えてもわかりません　　
間違ったままなのも嫌なのでQiita にもさらしてみることにしました  
  
元のブログの内容はゴミになってしまうので　　
最低限の基準として、一応動いたもの　　
レベルがかなり低いですが、・・・　　
 

今回は練習の登録  　

アンドロイドスタジオの入門でよくあるストップウォッチ  
参考になるコードはググると結構出てきます  
kotlinのものもありましたので、それを参考にさせていただきました  
  
  
参考にさせていただいたブログ  

[正式採用の「Kotlin」で挑戦！ 初めてのAndroidアプリ開発 〜ストップウォッチを作ってみよう〜](https://employment.en-japan.com/engineerhub/entry/2017/06/23/110000)  

[Kotlinのこと](https://qiita.com/0118takuUW/items/0b9e40ee86376342cb67)
  
アンドロイドスタジオはインストール済です

activity_main.xmlに  
経過時間表示用のTextView  
とボタン３つ追加  、それぞれIDをstart/stop/resetとしています

```activity_main.xml  
<?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"
    tools:context=".MainActivity">

    <TextView
        android:id="@+id/timeText"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/timer_zero"
        android:textSize="60sp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <Button
        android:id="@+id/start"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginStart="16dp"
        android:layout_marginTop="32dp"
        android:text="@string/command_start"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/timeText" />

    <Button
        android:id="@+id/stop"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginEnd="16dp"
        android:layout_marginStart="16dp"
        android:layout_marginTop="32dp"
        android:text="@string/command_stop"
        app:layout_constraintEnd_toStartOf="@+id/reset"
        app:layout_constraintStart_toEndOf="@+id/start"
        app:layout_constraintTop_toBottomOf="@+id/timeText" />

    <Button
        android:id="@+id/reset"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginEnd="16dp"
        android:layout_marginRight="16dp"
        android:layout_marginTop="32dp"
        android:text="@string/command_reset"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/timeText" />

</android.support.constraint.ConstraintLayout>
```  


ソースコードは

```activity_main.xmlMainActivity.kt  
package jp.example.hoge.stopwatch

import android.support.v7.app.AppCompatActivity
import android.os.Bundle
import android.os.Handler
import kotlinx.android.synthetic.main.activity_main.*

class MainActivity : AppCompatActivity() {
	val handler = Handler()						 //
	var timeValue = 0							   // 秒カウンター

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

		// Handler(スレット間通信：イベントキュー？)
		val runnable = object : Runnable {
			// メッセージ受信が有った時かな?
			override fun run() {
				timeValue++						 // 秒カウンタ+1
				timeToText(timeValue)?.let {		// timeToText()で表示データを作り
					timeText.text = it			  // timeText.textへ代入(表示)
			 }
				handler.postDelayed(this, 1000)	 // 1000ｍｓ後に自分にpost
			}
		}

		// startボタン押された時(setOnClickListener)の処理
		start.setOnClickListener {
			handler.post(runnable)				  // 最初のキュー登録
		}
		// stopボタン押された時の処理
		stop.setOnClickListener {
			handler.removeCallbacks(runnable)	   // キューキャンセル
		}
		// resetボタン押された時の処理
		reset.setOnClickListener {
			handler.removeCallbacks(runnable)	   // キューキャンセル
			timeValue = 0						   // 秒カウンタークリア
			timeToText()?.let {					 // timeToText()で表示データを作り
				timeText.text = it				  // timeText.textに表示
			}
		}
	}

	// 表示
	private fun timeToText(time: Int = 0): String? {
		return if (time < 0) {
			null									// 時刻が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. 開始で  
 handler.post(runnable)  
 最初のポストさせて  
2. ポストされると  
val runnable = object : Runnable {  
// ここが実行される  
}
3. その処理の最後に１秒後に自分にポストを予約  
handler.postDelayed(this, 1000)  
4. 停止は  
 handler.removeCallbacks(runnable)  
 リクエストのキャンセルを行ってます  


![sropwatch.png](https://qiita-image-store.s3.amazonaws.com/0/258658/0cc7b81d-80d0-1e1e-8943-c9dea99416be.png)

こんな感じで