Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 41 additions & 0 deletions app/src/main/java/com/example/bcsd_android_2025_1/LapAdapter.kt
Original file line number Diff line number Diff line change
@@ -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<LapAdapter.LapViewHolder>() {

private val lapList = mutableListOf<LapItem>()

inner class LapViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
private val lapTextView: TextView = itemView.findViewById(R.id.text_lap)

fun bind(item: LapItem) {
lapTextView.text = item.time
}
}

override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): LapViewHolder {
val view = LayoutInflater.from(parent.context).inflate(R.layout.item_lap, parent, false)
return LapViewHolder(view)
}

override fun onBindViewHolder(holder: LapViewHolder, position: Int) {
holder.bind(lapList[position])
}

override fun getItemCount(): Int = lapList.size

fun addLap(time: String) {
lapList.add(0, LapItem(time))
notifyItemInserted(0)
}

fun clear() {
lapList.clear()
notifyDataSetChanged()
}
}
5 changes: 5 additions & 0 deletions app/src/main/java/com/example/bcsd_android_2025_1/LapItem.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package com.example.bcsd_android_2025_1

data class LapItem(
val time: String
)
85 changes: 85 additions & 0 deletions app/src/main/java/com/example/bcsd_android_2025_1/MainActivity.kt
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,95 @@ import androidx.activity.enableEdgeToEdge
import androidx.appcompat.app.AppCompatActivity
import androidx.core.view.ViewCompat
import androidx.core.view.WindowInsetsCompat
import android.os.Handler
import android.os.Looper
import android.widget.Button
import android.widget.TextView
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView

class MainActivity : AppCompatActivity() {

private lateinit var timerTextView: TextView
private lateinit var startPauseButton: Button
private lateinit var stopButton: Button

private lateinit var lapButton: Button
private lateinit var lapRecyclerView: RecyclerView
private lateinit var lapAdapter: LapAdapter

private var isRunning = false
private var startTime = 0L
private var pauseOffset = 0L
private val handler = Handler(Looper.getMainLooper())


private val updateRunnable = object : Runnable {
override fun run() {
val elapsed = System.currentTimeMillis() - startTime
val minutes = (elapsed / 1000) / 60
val seconds = (elapsed / 1000) % 60
val milliseconds = (elapsed % 1000) / 10

val timeString = getString(R.string.formatted_timer, minutes, seconds, milliseconds)
timerTextView.text = timeString

handler.postDelayed(this, 10)
}
}

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
timerTextView = findViewById(R.id.timer_textview)
startPauseButton = findViewById(R.id.start_pause_button)
stopButton = findViewById(R.id.stop_button)

val defaultTimeString = getString(R.string.default_timer_text)

startPauseButton.setOnClickListener {
if (!isRunning) {
startTime = System.currentTimeMillis() - pauseOffset
handler.post(updateRunnable)
isRunning = true
startPauseButton.text = getString(R.string.button_pause)
} else {
pauseOffset = System.currentTimeMillis() - startTime
handler.removeCallbacks(updateRunnable)
isRunning = false
startPauseButton.text = getString(R.string.button_start)
}
}

stopButton.setOnClickListener {
handler.removeCallbacks(updateRunnable)
isRunning = false
pauseOffset = 0L
timerTextView.text = getString(R.string.default_timer_text)
startPauseButton.text = getString(R.string.button_start)
lapAdapter.clear()
}

lapButton = findViewById(R.id.lap_button)
lapRecyclerView = findViewById(R.id.lap_recyclerview)
lapAdapter = LapAdapter()

lapRecyclerView.apply {
adapter = lapAdapter
layoutManager = LinearLayoutManager(this@MainActivity)
}

lapButton.setOnClickListener {
if (isRunning) {
val elapsed = System.currentTimeMillis() - startTime
val minutes = (elapsed / 1000) / 60
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

확장함수로 구현할 수 있을 것 같네요

val seconds = (elapsed / 1000) % 60
val milliseconds = (elapsed % 1000) / 10

val lapTime = getString(R.string.formatted_timer, minutes, seconds, milliseconds)
lapAdapter.addLap(lapTime)
lapRecyclerView.scrollToPosition(0)
}
}
}
}
58 changes: 54 additions & 4 deletions app/src/main/res/layout/activity_main.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,65 @@
android:id="@+id/main"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="16dp"
tools:context=".MainActivity">

<TextView
android:layout_width="wrap_content"
android:id="@+id/timer_textview"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:text="Hello Android!"
app:layout_constraintBottom_toBottomOf="parent"
android:text="@string/default_timer_text"
android:textSize="48sp"
android:gravity="center"
android:textStyle="bold"
android:layout_marginTop="72dp"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent" />

<Button
android:id="@+id/start_pause_button"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:text="@string/button_start"
android:layout_marginTop="64dp"
app:layout_constraintEnd_toStartOf="@id/stop_button"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/timer_textview"
android:layout_marginEnd="8dp"/>

<Button
android:id="@+id/stop_button"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:text="@string/button_stop"
android:layout_marginTop="64dp"
app:layout_constraintTop_toBottomOf="@id/timer_textview"
app:layout_constraintStart_toEndOf="@id/start_pause_button"
app:layout_constraintEnd_toStartOf="@id/lap_button"
android:layout_marginStart="8dp"
android:layout_marginEnd="8dp"/>

<Button
android:id="@+id/lap_button"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:text="@string/button_lap"
android:layout_marginTop="64dp"
app:layout_constraintTop_toBottomOf="@id/timer_textview"
app:layout_constraintStart_toEndOf="@id/stop_button"
app:layout_constraintEnd_toEndOf="parent"
android:layout_marginStart="8dp"/>

<androidx.recyclerview.widget.RecyclerView
android:id="@+id/lap_recyclerview"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_marginTop="24dp"
app:layout_constraintTop_toBottomOf="@id/start_pause_button"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
app:layout_constraintEnd_toEndOf="parent"
tools:listitem="@layout/item_lap" />

</androidx.constraintlayout.widget.ConstraintLayout>
8 changes: 8 additions & 0 deletions app/src/main/res/layout/item_lap.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/text_lap"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="12dp"
android:textColor="@android:color/holo_green_dark"
android:textSize="16sp" />
6 changes: 6 additions & 0 deletions app/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
<resources>
<string name="app_name">BCSD_Android_2025-1</string>
<string name="button_start">Start</string>
<string name="button_pause">Pause</string>
<string name="button_stop">Stop</string>
<string name="button_lap">Lap</string>
<string name="default_timer_text">00 : 00 : 00</string>
<string name="formatted_timer">%1$02d : %2$02d : %3$02d</string>
</resources>