diff --git a/.idea/.name b/.idea/.name new file mode 100644 index 0000000..c4e4683 --- /dev/null +++ b/.idea/.name @@ -0,0 +1 @@ +BCSD_Android_2025-1 \ No newline at end of file diff --git a/.idea/AndroidProjectSystem.xml b/.idea/AndroidProjectSystem.xml new file mode 100644 index 0000000..4a53bee --- /dev/null +++ b/.idea/AndroidProjectSystem.xml @@ -0,0 +1,6 @@ + + + + + \ No newline at end of file diff --git a/.idea/compiler.xml b/.idea/compiler.xml new file mode 100644 index 0000000..b86273d --- /dev/null +++ b/.idea/compiler.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/.idea/deploymentTargetSelector.xml b/.idea/deploymentTargetSelector.xml new file mode 100644 index 0000000..b268ef3 --- /dev/null +++ b/.idea/deploymentTargetSelector.xml @@ -0,0 +1,10 @@ + + + + + + + + + \ No newline at end of file diff --git a/.idea/gradle.xml b/.idea/gradle.xml new file mode 100644 index 0000000..639c779 --- /dev/null +++ b/.idea/gradle.xml @@ -0,0 +1,19 @@ + + + + + + + \ No newline at end of file diff --git a/.idea/kotlinc.xml b/.idea/kotlinc.xml new file mode 100644 index 0000000..c224ad5 --- /dev/null +++ b/.idea/kotlinc.xml @@ -0,0 +1,6 @@ + + + + + \ No newline at end of file diff --git a/.idea/migrations.xml b/.idea/migrations.xml new file mode 100644 index 0000000..f8051a6 --- /dev/null +++ b/.idea/migrations.xml @@ -0,0 +1,10 @@ + + + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..2cdc89a --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/.idea/runConfigurations.xml b/.idea/runConfigurations.xml new file mode 100644 index 0000000..16660f1 --- /dev/null +++ b/.idea/runConfigurations.xml @@ -0,0 +1,17 @@ + + + + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000..35eb1dd --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file 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..283a23c --- /dev/null +++ b/app/src/main/java/com/example/bcsd_android_2025_1/LapAdapter.kt @@ -0,0 +1,41 @@ +package com.example.bcsd_android_2025_1 + +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import android.widget.TextView +import androidx.recyclerview.widget.RecyclerView + +class LapAdapter : RecyclerView.Adapter() { + + private val lapTimes = mutableListOf() + + inner class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) { + val lapMessage: TextView = itemView.findViewById(R.id.tv_item_message) + val lapRecord: TextView = itemView.findViewById(R.id.tv_item_record) + } + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder { + val view = LayoutInflater.from(parent.context) + .inflate(R.layout.item, parent, false) + return ViewHolder(view) + } + + override fun onBindViewHolder(holder: ViewHolder, position: Int) { + holder.lapMessage.text = holder.itemView.context.getString(R.string.tv_message) + holder.lapRecord.text = lapTimes[position] + } + + override fun getItemCount(): Int = lapTimes.size + + fun addLap(lap: String) { + lapTimes.add(0, lap) + notifyItemInserted(0) + } + + fun clear() { + lapTimes.clear() + notifyDataSetChanged() + } + +} \ 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..a78eebb 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,97 @@ package com.example.bcsd_android_2025_1 - import android.os.Bundle -import androidx.activity.enableEdgeToEdge +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 androidx.recyclerview.widget.LinearLayoutManager +import androidx.recyclerview.widget.RecyclerView +import kotlinx.coroutines.Job +import kotlinx.coroutines.delay +import kotlinx.coroutines.isActive +import kotlinx.coroutines.launch class MainActivity : AppCompatActivity() { + + private lateinit var tvTimer : TextView + private lateinit var btnLap : Button + private lateinit var btnStart : Button + private lateinit var btnStop : Button + + private lateinit var rvRecord : RecyclerView + private lateinit var lapAdapter: LapAdapter + + private var isRunning = false + private var runningTime = 0L + private var job: Job? = null + override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) + + tvTimer = findViewById(R.id.tv_main_timer) + btnLap = findViewById(R.id.btn_main_lap) + btnStart = findViewById(R.id.btn_main_start) + btnStop = findViewById(R.id.btn_main_stop) + rvRecord = findViewById(R.id.rv_main_record) + rvRecord.layoutManager = LinearLayoutManager(this) + lapAdapter = LapAdapter() + rvRecord.adapter = lapAdapter + + btnStart.setOnClickListener { + if (isRunning) { + pauseTimer() + } else { + startTimer() + } + } + + btnStop.setOnClickListener { + stopTimer() + } + + btnLap.setOnClickListener { + if (isRunning) { + lapAdapter.addLap(formatTime(runningTime)) + } + } + } + + private fun startTimer() { + val startTime = System.currentTimeMillis() - runningTime + job = lifecycleScope.launch { + while (isActive) { + runningTime = System.currentTimeMillis() - startTime + tvTimer.text = formatTime(runningTime) + delay(10) + } + } + isRunning = true + btnStart.text = getString(R.string.btn_pause) + } + + private fun pauseTimer() { + job?.cancel() + isRunning = false + btnStart.text = getString(R.string.btn_start) + } + + private fun stopTimer() { + job?.cancel() + runningTime = 0L + isRunning = false + tvTimer.text = getString(R.string.tv_time) + btnStart.text = getString(R.string.btn_start) + lapAdapter.clear() } -} \ No newline at end of file + + private fun formatTime(ms: Long): String { + val min = (ms/1000)/60 + val sec = (ms/1000)%60 + val millisec = (ms%1000) / 10 + return String.format("%02d:%02d:%02d", min, sec, millisec) + } + + +} + diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml index 311f3cb..29e6363 100644 --- a/app/src/main/res/layout/activity_main.xml +++ b/app/src/main/res/layout/activity_main.xml @@ -8,12 +8,52 @@ tools:context=".MainActivity"> + +