diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 5791375..d8fbcd4 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -36,6 +36,9 @@ android { } dependencies { +//coroutine + implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.10.2") + implementation("org.jetbrains.kotlinx:kotlinx-coroutines-android:1.10.2") implementation(libs.androidx.core.ktx) implementation(libs.androidx.appcompat) diff --git a/app/src/main/java/com/example/bcsd_android_2025_1/LapAdapter.kt b/app/src/main/java/com/example/bcsd_android_2025_1/LapAdapter.kt new file mode 100644 index 0000000..e49b1ca --- /dev/null +++ b/app/src/main/java/com/example/bcsd_android_2025_1/LapAdapter.kt @@ -0,0 +1,33 @@ +package com.example.bcsd_android_2025_1 + +import LapData +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import android.widget.TextView +import androidx.recyclerview.widget.RecyclerView + +class LapAdapter(private val lapList: List) : + RecyclerView.Adapter() { + + class LapViewHolder(view: View) : RecyclerView.ViewHolder(view) { + val number: TextView = view.findViewById(R.id.lap_text_number) + val section: TextView = view.findViewById(R.id.lap_text_sectionRecord) + val total: TextView = view.findViewById(R.id.lap_text_totalTime) + } + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): LapViewHolder { + val view = LayoutInflater.from(parent.context) + .inflate(R.layout.lap_list, parent, false) + return LapViewHolder(view) + } + + override fun onBindViewHolder(holder: LapViewHolder, position: Int) { + val lap = lapList[position] + holder.number.text = lap.number.toString() + holder.section.text = lap.sectionTime + holder.total.text = lap.totalTime + } + + override fun getItemCount() = lapList.size +} diff --git a/app/src/main/java/com/example/bcsd_android_2025_1/LapData.kt b/app/src/main/java/com/example/bcsd_android_2025_1/LapData.kt new file mode 100644 index 0000000..647ebcc --- /dev/null +++ b/app/src/main/java/com/example/bcsd_android_2025_1/LapData.kt @@ -0,0 +1,5 @@ +data class LapData( + val number: Int, + val sectionTime: String, + val totalTime: String +) \ No newline at end of file diff --git a/app/src/main/java/com/example/bcsd_android_2025_1/MainActivity.kt b/app/src/main/java/com/example/bcsd_android_2025_1/MainActivity.kt index 3ffa0eb..3aa9bd3 100644 --- a/app/src/main/java/com/example/bcsd_android_2025_1/MainActivity.kt +++ b/app/src/main/java/com/example/bcsd_android_2025_1/MainActivity.kt @@ -1,14 +1,119 @@ package com.example.bcsd_android_2025_1 +import LapData import android.os.Bundle -import androidx.activity.enableEdgeToEdge +import android.os.SystemClock +import android.widget.Button +import android.widget.TextView import androidx.appcompat.app.AppCompatActivity -import androidx.core.view.ViewCompat -import androidx.core.view.WindowInsetsCompat +import androidx.lifecycle.lifecycleScope +import kotlinx.coroutines.Job +import kotlinx.coroutines.delay +import kotlinx.coroutines.launch +import androidx.recyclerview.widget.LinearLayoutManager +import androidx.recyclerview.widget.RecyclerView class MainActivity : AppCompatActivity() { + + private lateinit var timerText: TextView + private lateinit var startButton: Button + private lateinit var stopButton: Button + private lateinit var lapButton: Button + private lateinit var lapRecyclerView: RecyclerView + private lateinit var lapAdapter: LapAdapter + private val lapList = mutableListOf() + + private var isRunning = false + private var startTime = 0L // 시작시간 + private var beforeTime = 0L // 누적시간 + private var timerJob: Job? = null // 중단 위함 + private var lastLapTime = 0L // 마지막 기록된 시간 + override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) + + timerText = findViewById(R.id.main_text_timer) + startButton = findViewById(R.id.main_button_start) + stopButton = findViewById(R.id.main_button_stop) + lapButton = findViewById(R.id.main_button_lap) + lapRecyclerView = findViewById(R.id.main_recycler_lap) + + lapAdapter = LapAdapter(lapList) + lapRecyclerView.adapter = lapAdapter + lapRecyclerView.layoutManager = LinearLayoutManager(this) + + startButton.setOnClickListener { + if (!isRunning) { + startTimer() + } else { + pauseTimer() + } + } + + stopButton.setOnClickListener { + stopTimer() + } + + lapButton.setOnClickListener { + if (!isRunning) return@setOnClickListener + + val now = SystemClock.elapsedRealtime() + val total = now - startTime + beforeTime + val section = if (lapList.isEmpty()) total else total - lastLapTime + lastLapTime = total + + val lap = LapData( + number = lapList.size + 1, + sectionTime = formatTime(section), + totalTime = formatTime(total) + ) + + lapList.add(0, lap) + lapAdapter.notifyItemInserted(0) + lapRecyclerView.scrollToPosition(0) + } + } + + private fun startTimer() { + isRunning = true + startButton.text = getString(R.string.main_pause) + startTime = SystemClock.elapsedRealtime() // 시작시점 + + timerJob = lifecycleScope.launch { + while (isRunning) { + val now = SystemClock.elapsedRealtime() + val totalTime = now - startTime + beforeTime // 총 누적 시간 = 현재 시간 - 시작시간 + 이전누적시간 + timerText.text = formatTime(totalTime) + delay(10) // 10ms마다 갱신 + } + } + } + + private fun pauseTimer() { + isRunning = false + beforeTime += SystemClock.elapsedRealtime() - startTime // 이전 누적 시간에 이번에 흐른 시간 더함. + timerJob?.cancel() + startButton.text = getString(R.string.main_start) + } + + private fun formatTime(ms: Long): String { + val minutes = ms / 1000 / 60 + val seconds = (ms / 1000) % 60 + val millis = (ms % 1000) / 10 + return String.format("%02d : %02d : %02d", minutes, seconds, millis) + } + + private fun stopTimer() { + isRunning = false + timerJob?.cancel() // 코루틴 정지 + 기록 초기화 + startTime = 0L + beforeTime = 0L + lastLapTime = 0L + timerText.text = getString(R.string.main_default_time) + startButton.text = getString(R.string.main_start) + + lapList.clear() + lapAdapter.notifyDataSetChanged() } } \ No newline at end of file diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml index 311f3cb..cce19e8 100644 --- a/app/src/main/res/layout/activity_main.xml +++ b/app/src/main/res/layout/activity_main.xml @@ -8,12 +8,103 @@ tools:context=".MainActivity"> + +