Skip to content

Commit 2d46e99

Browse files
authored
Merge pull request #425 from projects200/refactor/timer-input-423
[Refactor] 타이머 시간 선택 리팩토링 #423
2 parents a841049 + b5a9b35 commit 2d46e99

File tree

3 files changed

+103
-36
lines changed

3 files changed

+103
-36
lines changed

feature/timer/src/main/java/com/project200/feature/timer/TimePickerDialog.kt

Lines changed: 44 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,10 @@ package com.project200.feature.timer
33
import android.graphics.Color
44
import android.view.View
55
import android.view.WindowManager
6+
import android.widget.EditText
67
import androidx.core.graphics.drawable.toDrawable
78
import com.project200.presentation.base.BaseDialogFragment
9+
import com.project200.presentation.utils.TimeEditTextLimiter.addRangeLimit
810
import com.project200.undabang.feature.timer.R
911
import com.project200.undabang.feature.timer.databinding.DialogTimePickerBinding
1012
import dagger.hilt.android.AndroidEntryPoint
@@ -14,28 +16,29 @@ import java.util.Locale
1416
class TimePickerDialog(
1517
private val initialTime: Int? = null,
1618
private val onTimeSelected: (Int) -> Unit,
17-
) :
18-
BaseDialogFragment<DialogTimePickerBinding>(R.layout.dialog_time_picker) {
19+
) : BaseDialogFragment<DialogTimePickerBinding>(R.layout.dialog_time_picker) {
1920
override fun getViewBinding(view: View): DialogTimePickerBinding {
2021
return DialogTimePickerBinding.bind(view)
2122
}
2223

2324
override fun setupViews() {
2425
super.setupViews()
2526

27+
// 다이얼로그 가로 너비 및 배경 투명화 설정
2628
dialog?.window?.let { window ->
2729
val screenWidth = resources.displayMetrics.widthPixels
2830
val desiredWidth = (screenWidth * 0.85).toInt()
2931
window.setLayout(desiredWidth, WindowManager.LayoutParams.WRAP_CONTENT)
3032
window.setBackgroundDrawable(Color.TRANSPARENT.toDrawable())
3133
}
3234

33-
setupTimePickers()
35+
setupTimeInputs()
36+
setupFocusAndRangeListeners()
3437

3538
binding.confirmBtn.setOnClickListener {
36-
// NumberPicker에서 선택된 분과 초를 가져옵니다.
37-
val minutes = binding.minutePicker.value
38-
val seconds = binding.secondPicker.value
39+
// 빈 칸일 경우 0으로 처리, 범위 재확인
40+
val minutes = (binding.minuteEt.text.toString().toIntOrNull() ?: 0).coerceIn(0, 59)
41+
val seconds = (binding.secondEt.text.toString().toIntOrNull() ?: 0).coerceIn(0, 59)
3942
val totalTimeInSeconds = (minutes * 60) + seconds
4043

4144
onTimeSelected(totalTimeInSeconds)
@@ -47,22 +50,43 @@ class TimePickerDialog(
4750
}
4851
}
4952

50-
private fun setupTimePickers() {
51-
binding.minutePicker.apply {
52-
minValue = 0
53-
maxValue = 59 // 최대 59분
54-
value = initialTime?.div(60) ?: 0 // 초기값이 null인 경우 0으로 설정
55-
setFormatter { String.format(Locale.KOREA, "%02d", it) }
56-
}
53+
private fun setupTimeInputs() {
54+
// 초 단위를 분과 초로 계산하여 초기값 설정
55+
val minutes = initialTime?.div(60) ?: 0
56+
val seconds = initialTime?.rem(60) ?: 0
5757

58-
binding.secondPicker.apply {
59-
minValue = 0
60-
maxValue = 59 // 최대 59초
61-
value = initialTime?.rem(60) ?: 0 // 초기값이 null인 경우 0으로 설정
62-
setFormatter { String.format(Locale.KOREA, "%02d", it) }
63-
}
58+
binding.minuteEt.setText(String.format(Locale.KOREA, "%02d", minutes))
59+
binding.secondEt.setText(String.format(Locale.KOREA, "%02d", seconds))
6460
}
6561

66-
companion object {
62+
private fun setupFocusAndRangeListeners() {
63+
// 1. 포커스 상태에 따른 배경 및 포맷팅 처리
64+
val focusChangeListener =
65+
View.OnFocusChangeListener { view, hasFocus ->
66+
if (view is EditText) {
67+
if (hasFocus) {
68+
// 포커스 얻었을 때: 배경 적용 및 텍스트 전체 선택
69+
view.setBackgroundResource(com.project200.undabang.presentation.R.drawable.bg_solid_corner)
70+
view.selectAll()
71+
} else {
72+
// 포커스 잃었을 때: 배경 제거 및 00~59 보정 후 포맷팅
73+
view.setBackgroundResource(0)
74+
val input = view.text.toString().toIntOrNull() ?: 0
75+
val clamped = input.coerceIn(0, 59)
76+
view.setText(String.format(Locale.KOREA, "%02d", clamped))
77+
}
78+
}
79+
}
80+
81+
binding.minuteEt.onFocusChangeListener = focusChangeListener
82+
binding.secondEt.onFocusChangeListener = focusChangeListener
83+
84+
// 실시간 입력 범위 제한 (0~59)
85+
binding.minuteEt.addRangeLimit(59)
86+
binding.secondEt.addRangeLimit(59)
87+
88+
// 초기 상태 배경 제거
89+
binding.minuteEt.setBackgroundResource(0)
90+
binding.secondEt.setBackgroundResource(0)
6791
}
6892
}

feature/timer/src/main/res/layout/dialog_time_picker.xml

Lines changed: 56 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -2,32 +2,72 @@
22
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
33
android:layout_width="match_parent"
44
android:layout_height="wrap_content"
5+
xmlns:app="http://schemas.android.com/apk/res-auto"
56
android:orientation="vertical"
67
android:background="@drawable/dialog_radius"
78
android:padding="@dimen/base_horizontal_margin">
89

9-
<LinearLayout
10+
<androidx.constraintlayout.widget.ConstraintLayout
1011
android:layout_width="match_parent"
1112
android:layout_height="wrap_content"
12-
android:orientation="horizontal"
13-
android:gravity="center_vertical"
1413
android:layout_margin="24dp">
15-
16-
<NumberPicker
17-
android:id="@+id/minute_picker"
18-
android:layout_width="0dp"
14+
<TextView
15+
android:layout_width="wrap_content"
1916
android:layout_height="wrap_content"
20-
android:layout_weight="1"
21-
android:descendantFocusability="blocksDescendants"/>
17+
style="@style/subtext_14"
18+
android:text="@string/minute"
19+
android:layout_marginBottom="6dp"
20+
app:layout_constraintStart_toStartOf="@id/minute_et"
21+
app:layout_constraintEnd_toEndOf="@id/minute_et"
22+
app:layout_constraintBottom_toTopOf="@id/minute_et"/>
23+
<EditText
24+
android:id="@+id/minute_et"
25+
android:background="@null"
26+
android:layout_width="100dp"
27+
android:layout_height="70dp"
28+
style="@style/content_regular"
29+
android:textSize="40sp"
30+
android:maxLength="2"
31+
android:gravity="center"
32+
android:maxLines="1"
33+
android:inputType="numberSigned"
34+
app:layout_constraintStart_toStartOf="parent"
35+
app:layout_constraintBottom_toBottomOf="parent"/>
2236

23-
<NumberPicker
24-
android:id="@+id/second_picker"
25-
android:layout_width="0dp"
37+
<TextView
38+
style="@style/content_regular"
39+
android:layout_width="wrap_content"
2640
android:layout_height="wrap_content"
27-
android:layout_marginStart="20dp"
28-
android:layout_weight="1"
29-
android:descendantFocusability="blocksDescendants"/>
30-
</LinearLayout>
41+
android:layout_gravity="center"
42+
android:text="@string/time_divider"
43+
android:textSize="40sp"
44+
app:layout_constraintBottom_toBottomOf="parent"
45+
app:layout_constraintEnd_toStartOf="@+id/second_et"
46+
app:layout_constraintStart_toEndOf="@id/minute_et"
47+
app:layout_constraintTop_toTopOf="@+id/minute_et" />
48+
<TextView
49+
android:layout_width="wrap_content"
50+
android:layout_height="wrap_content"
51+
style="@style/subtext_14"
52+
android:text="@string/second"
53+
android:layout_marginBottom="6dp"
54+
app:layout_constraintStart_toStartOf="@id/second_et"
55+
app:layout_constraintEnd_toEndOf="@id/second_et"
56+
app:layout_constraintBottom_toTopOf="@id/second_et"/>
57+
<EditText
58+
android:id="@+id/second_et"
59+
android:background="@null"
60+
android:layout_width="100dp"
61+
android:layout_height="70dp"
62+
style="@style/content_regular"
63+
android:textSize="40sp"
64+
android:inputType="numberSigned"
65+
android:maxLength="2"
66+
android:maxLines="1"
67+
android:gravity="center"
68+
app:layout_constraintEnd_toEndOf="parent"
69+
app:layout_constraintBottom_toBottomOf="parent"/>
70+
</androidx.constraintlayout.widget.ConstraintLayout>
3171

3272
<LinearLayout
3373
android:layout_width="match_parent"

feature/timer/src/main/res/values/strings.xml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,9 @@
1414
<string name="timer_start">시작</string>
1515
<string name="timer_stop">일시 정지</string>
1616
<string name="timer_end">종료</string>
17+
<string name="minute">분</string>
18+
<string name="second">초</string>
19+
<string name="time_divider">:</string>
1720

1821
<string name="custom_timer_notify_title_format">%1$d / %2$d %3$s</string>
1922
<string name="timer_notify_time_format">%02d:%02d</string>

0 commit comments

Comments
 (0)