Skip to content

Commit

Permalink
✨ timer customizing
Browse files Browse the repository at this point in the history
  • Loading branch information
ii2001 committed Sep 19, 2024
1 parent 6444ae8 commit c17f117
Show file tree
Hide file tree
Showing 7 changed files with 183 additions and 31 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,10 @@ class RecipeStepFragment : Fragment() {
get() = _binding!!

private val recipeStepPagerRecyclerAdapter: RecipeStepPagerRecyclerAdapter by lazy {
RecipeStepPagerRecyclerAdapter(viewPager2 = binding.vpStepRecipe)
RecipeStepPagerRecyclerAdapter(
viewPager2 = binding.vpStepRecipe,
fragmentManager = childFragmentManager
)
}


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package net.pengcook.android.presentation.step

import android.view.LayoutInflater
import android.view.ViewGroup
import androidx.fragment.app.FragmentManager
import androidx.recyclerview.widget.RecyclerView
import androidx.viewpager2.widget.ViewPager2
import net.pengcook.android.databinding.ItemStepRecipeBinding
Expand All @@ -10,6 +11,7 @@ import net.pengcook.android.presentation.core.model.RecipeStep
class RecipeStepPagerRecyclerAdapter(
private var pageList: List<RecipeStep> = emptyList(),
private val viewPager2: ViewPager2,
private val fragmentManager: FragmentManager,
) : RecyclerView.Adapter<RecipeStepViewHolder>() {

override fun onCreateViewHolder(
Expand All @@ -19,7 +21,7 @@ class RecipeStepPagerRecyclerAdapter(
val binding = ItemStepRecipeBinding.inflate(
LayoutInflater.from(parent.context), parent, false
)
return RecipeStepViewHolder(binding)
return RecipeStepViewHolder(binding, fragmentManager = fragmentManager)
}

override fun getItemCount(): Int = pageList.size
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,47 +2,66 @@ package net.pengcook.android.presentation.step

import android.os.CountDownTimer
import android.view.View
import androidx.fragment.app.FragmentManager
import androidx.recyclerview.widget.RecyclerView
import net.pengcook.android.databinding.ItemStepRecipeBinding
import net.pengcook.android.presentation.core.model.RecipeStep

class RecipeStepViewHolder(
private val binding: ItemStepRecipeBinding,
) : RecyclerView.ViewHolder(binding.root) {
private val fragmentManager: FragmentManager,
) : RecyclerView.ViewHolder(binding.root), TimerSettingDialogFragment.TimerSettingListener {

private var isTimerRunning = false
private var countDownTimer: CountDownTimer? = null

fun bind(recipeStep: RecipeStep, moveToNextStep: () -> Unit) {
binding.recipeStep = recipeStep
private var moveToNextStep: (() -> Unit)? = null

val cookingTimeInSeconds = convertToSeconds(recipeStep.cookingTime)
private var cookingTimeInMillis: Long = 0L

binding.timer.tvTimer.text = formatTime(cookingTimeInSeconds * 1000)
fun bind(recipeStep: RecipeStep, moveToNextStep: () -> Unit) {
this.moveToNextStep = moveToNextStep
binding.recipeStep = recipeStep

val clickListener = View.OnClickListener {
when {
cookingTimeInSeconds <= 1 -> {
moveToNextStep()
}
cookingTimeInMillis = convertToMillis(recipeStep.cookingTime)
binding.timer.tvTimer.text = formatTime(cookingTimeInMillis)

!isTimerRunning -> {
startTimer(cookingTimeInSeconds * 1000, moveToNextStep)
isTimerRunning = true
}
val timerClickListener = View.OnClickListener {
showTimerSettingDialog()
}
binding.clickListener = timerClickListener

else -> {
stopTimer()
moveToNextStep()
}
val contentClickListener = View.OnClickListener {
if (!isTimerRunning) {
startTimer(cookingTimeInMillis)
isTimerRunning = true
} else {
stopTimer()
moveToNextStep()
}
}
binding.clickListener = clickListener
binding.contentClickListener = contentClickListener

binding.executePendingBindings()
}

private fun startTimer(durationInMillis: Long, moveToNextStep: () -> Unit) {
private fun showTimerSettingDialog() {
val dialog = TimerSettingDialogFragment()
dialog.listener = this
dialog.show(fragmentManager, "TimerSettingDialog")
}

override fun onTimeSet(minutes: Int, seconds: Int) {
val totalMillis = (minutes * 60 + seconds) * 1000L
cookingTimeInMillis = totalMillis

binding.timer.tvTimer.text = formatTime(cookingTimeInMillis)
isTimerRunning = false
countDownTimer?.cancel()
countDownTimer = null
}

private fun startTimer(durationInMillis: Long) {
countDownTimer = object : CountDownTimer(durationInMillis, 1000) {
override fun onTick(millisUntilFinished: Long) {
binding.timer.tvTimer.text = formatTime(millisUntilFinished)
Expand All @@ -51,7 +70,7 @@ class RecipeStepViewHolder(
override fun onFinish() {
binding.timer.tvTimer.text = "00:00"
isTimerRunning = false
moveToNextStep()
moveToNextStep?.invoke()
}
}.start()
}
Expand All @@ -68,11 +87,11 @@ class RecipeStepViewHolder(
return String.format("%02d:%02d", minutes, seconds)
}

private fun convertToSeconds(time: String): Long {
private fun convertToMillis(time: String): Long {
val timeParts = time.split(":")
val hours = timeParts.getOrNull(0)?.toIntOrNull() ?: 0
val minutes = timeParts.getOrNull(1)?.toIntOrNull() ?: 0
val seconds = timeParts.getOrNull(2)?.toIntOrNull() ?: 0
return (hours * 3600 + minutes * 60 + seconds).toLong()
val hours = timeParts.getOrNull(0)?.toLongOrNull() ?: 0L
val minutes = timeParts.getOrNull(1)?.toLongOrNull() ?: 0L
val seconds = timeParts.getOrNull(2)?.toLongOrNull() ?: 0L
return (hours * 3600 + minutes * 60 + seconds) * 1000L
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
package net.pengcook.android.presentation.step

import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.DialogFragment
import net.pengcook.android.databinding.DialogTimerSettingBinding

class TimerSettingDialogFragment : DialogFragment() {

private var _binding: DialogTimerSettingBinding? = null
private val binding get() = _binding!!

interface TimerSettingListener {
fun onTimeSet(minutes: Int, seconds: Int)
}

var listener: TimerSettingListener? = null

override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?,
): View {
_binding = DialogTimerSettingBinding.inflate(inflater, container, false)
return binding.root
}

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)

setupNumberPickers()

binding.btnConfirm.setOnClickListener {
val minutes = binding.npMinutes.value
val seconds = binding.npSeconds.value
listener?.onTimeSet(minutes, seconds)
dismiss()
}

binding.btnCancel.setOnClickListener {
dismiss()
}
}

private fun setupNumberPickers() {
binding.npMinutes.minValue = 0
binding.npMinutes.maxValue = 59
binding.npMinutes.wrapSelectorWheel = true

binding.npSeconds.minValue = 0
binding.npSeconds.maxValue = 59
binding.npSeconds.wrapSelectorWheel = true
}

override fun onDestroyView() {
super.onDestroyView()
_binding = null
}
}
63 changes: 63 additions & 0 deletions android/app/src/main/res/layout/dialog_timer_setting.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">

<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="16dp">

<TextView
android:id="@+id/tv_description"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="8dp"
android:text="Set Timer"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />

<!-- 분 설정 NumberPicker -->
<NumberPicker
android:id="@+id/np_minutes"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="8dp"
app:layout_constraintEnd_toStartOf="@+id/np_seconds"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/tv_description" />

<!-- 초 설정 NumberPicker -->
<NumberPicker
android:id="@+id/np_seconds"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@id/np_minutes"
app:layout_constraintTop_toBottomOf="@id/tv_description" />

<!-- 확인 및 취소 버튼 -->
<Button
android:id="@+id/btn_cancel"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:layout_marginEnd="8dp"
android:backgroundTint="@color/yellow_strong"
android:text="cancle"
app:layout_constraintEnd_toStartOf="@id/btn_confirm"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/np_minutes" />

<Button
android:id="@+id/btn_confirm"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:backgroundTint="@color/yellow_strong"
android:text="confirm"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@id/btn_cancel"
app:layout_constraintTop_toBottomOf="@id/np_minutes" />

</androidx.constraintlayout.widget.ConstraintLayout>
</layout>
9 changes: 6 additions & 3 deletions android/app/src/main/res/layout/item_step_recipe.xml
Original file line number Diff line number Diff line change
Expand Up @@ -9,20 +9,24 @@
name="recipeStep"
type="net.pengcook.android.presentation.core.model.RecipeStep" />

<variable
name="contentClickListener"
type="android.view.View.OnClickListener" />

<variable
name="clickListener"
type="android.view.View.OnClickListener" />
</data>

<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
android:layout_height="match_parent"
android:onClick="@{contentClickListener}">

<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/cl_image_container"
android:layout_width="0dp"
android:layout_height="0dp"
android:onClick="@{clickListener}"
app:layout_constraintDimensionRatio="8:7"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
Expand Down Expand Up @@ -58,7 +62,6 @@
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_margin="20dp"
android:onClick="@{clickListener}"
android:text="@{recipeStep.description}"
android:textSize="15sp"
app:layout_constraintBottom_toBottomOf="parent"
Expand Down
1 change: 1 addition & 0 deletions android/app/src/main/res/layout/item_timer.xml
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@drawable/shape_timer_round_corner"
android:onClick="@{clickListener}"
android:paddingHorizontal="30dp"
android:paddingVertical="5dp">

Expand Down

0 comments on commit c17f117

Please sign in to comment.