How to stop all chronometers of items in RecyclerView even those ones are hidden? KOTLIN

122 views Asked by At

I Shared with group to build a Task Timer App, which start timer (stopWatch) when you click on item and when you click again it will stop timer. I used Android Chronometer for that and put it for each item in recyclerview

I faced problem when user start a first timer then scroll down the first one will stopped even the user does not stop it. So I hope to find someone to help me to solve this issue

Thank you

this is an app https://github.com/hsn-amr/Task-Timer

this is a recyclerview adapter

package com.example.tasktimer

import android.app.Application
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.recyclerview.widget.RecyclerView
import com.example.tasktimer.model.Task
import com.example.tasktimer.viewmodel.TaskViewModel
import kotlinx.android.synthetic.main.item_row.view.*
import android.os.SystemClock
import android.util.Log
import android.widget.Chronometer
import androidx.core.view.doOnDetach
import androidx.core.view.isVisible
import com.example.tasktimer.fragments.ViewFragment
import kotlinx.android.synthetic.main.fragment_view.view.*
import androidx.recyclerview.widget.LinearLayoutManager

class HomeRecyclerView(application: Application, val viewFragment: ViewFragment):
    RecyclerView.Adapter<HomeRecyclerView.ItemViewHolder>() {
    class ItemViewHolder( itemView: View): RecyclerView.ViewHolder(itemView)

    private var tasks = emptyList<Task>()
    private val taskViewModel by lazy { TaskViewModel(application) }

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ItemViewHolder {
        return ItemViewHolder(
            LayoutInflater.from(parent.context).inflate(
                R.layout.item_row,
                parent,
                false
            )
        )
    }

    override fun onBindViewHolder(holder: ItemViewHolder, position: Int) {

        holder.setIsRecyclable(false)
        val task = tasks[position]

        holder.itemView.apply {
            tvTitleInHome.text = task.task
            chronometer.text = task.timer

            if(task.active){
                chronometer.text = task.timer
                viewFragment.mainTitle.text = task.task
                chronometer.base = SystemClock.elapsedRealtime() - task.pauseOffset
                chronometer.start()
                chronometer.onChronometerTickListener = Chronometer.OnChronometerTickListener { chronometer ->
                    viewFragment.mainTime.text = chronometer.text
                }
            }

            tvTitleInHome.setOnClickListener {

                viewFragment.mainTitle.text = task.task

                if(!task.active){
                    viewFragment.stopAllOtherTimers(viewFragment.tasks, task.id)
                    chronometer.base = SystemClock.elapsedRealtime() - task.pauseOffset
                    chronometer.start()
                    task.active = true
                    taskViewModel.updateTask(task)
                    viewFragment.showingButtons(false)
                }else{
                    task.timer = chronometer.text.toString()
                    chronometer.stop()
                    task.pauseOffset = SystemClock.elapsedRealtime() - chronometer.base
                    task.active = false
                    chronometer.text = task.timer
                    taskViewModel.updateTask(task)
                    viewFragment.showingButtons(true)
                }

                chronometer.onChronometerTickListener = Chronometer.OnChronometerTickListener { chronometer ->
                    viewFragment.mainTime.text = chronometer.text
                }

                viewFragment.pauseButton.setOnClickListener {
                    pauseTimer(task, chronometer)
                }

                viewFragment.restartButton.setOnClickListener {
                    restartTimer(task, chronometer)
                }
            }
        }

    }


    fun pauseTimer(task: Task, chronometer: Chronometer){
        chronometer.base = SystemClock.elapsedRealtime() - task.pauseOffset
        chronometer.start()
        task.active = true
        taskViewModel.updateTask(task)
        viewFragment.showingButtons(false)
    }

    fun restartTimer(task:Task, chronometer: Chronometer){
        task.totalTime = getTotalFromString(task.totalTime, chronometer.text.toString())
        chronometer.base = SystemClock.elapsedRealtime()
        task.pauseOffset = 0
        chronometer.start()
        task.active = true
        taskViewModel.updateTask(task)
        viewFragment.showingButtons(false)
    }

    override fun getItemCount() = tasks.size

    fun update(tasks: List<Task>){
        this.tasks = tasks
        notifyDataSetChanged()
    }

    private fun getTotalFromString(oldString:String, newString: String): String {
        var oldHours = 0
        var oldMinutes = 0
        var oldSeconds = 0
        val oldStringArray = oldString.split(":")
        if(oldStringArray.size == 2){
            oldMinutes = oldStringArray[0].toInt()
            oldSeconds = oldStringArray[1].toInt()
        }else{
            oldHours = oldStringArray[0].toInt()
            oldMinutes = oldStringArray[1].toInt()
            oldSeconds = oldStringArray[2].toInt()
        }

        var newHours = 0
        var newMinutes = 0
        var newSeconds = 0
        val newStringArray = newString.split(":")
        if(newStringArray.size == 2){
            newMinutes = newStringArray[0].toInt() + oldMinutes
            newSeconds = newStringArray[1].toInt() + oldSeconds
        }else{
            newHours = newStringArray[0].toInt() + oldHours
            newMinutes = newStringArray[1].toInt() + oldMinutes
            newSeconds = newStringArray[2].toInt() + oldSeconds
        }

        if(newSeconds>=60){
            newMinutes += newSeconds/60
            newSeconds %= 60
        }
        if(newMinutes>=60){
            newHours += newMinutes/60
            newMinutes %= 60
        }

        val result = (if (newHours < 10) "0$newHours" else newHours).toString() +
                ":" + (if (newMinutes < 10) "0$newMinutes" else newMinutes) +
                ":" + if (newSeconds < 10) "0$newSeconds" else newSeconds

        return result
    }

}
0

There are 0 answers