How to have Android chronometer to operate in both count Up & Down modes

464 Views Asked by At

Im investigating Android Chronometer widget

I would like one Chronometer to work either as a countUp timer or countDown timer and having difficulty in understanding how I set the Chronometer.base to achieve this.

My Chronometer is defined in xml as follows:-

    <Chronometer
        android:id="@+id/chronometer_one"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:background="@drawable/border"
        android:padding="10dp"
        android:textAlignment="center"
        android:textAppearance="@style/TextAppearance.AppCompat.Large"
        android:textColor="?android:attr/textColorPrimary" />

The count up mode works perfectly with this Kotlin code:-

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_speedometer)

    chronometerOne = findViewById(R.id.chronometer_one)
    chronometerOne.text = resources.getString(R.string.start_time)

    startStopButtonOne = findViewById(R.id.stop_start_button_one)

    chronometerOne.setOnChronometerTickListener { chronometer -> formatTime(chronometer) }

    startStopButtonOne.setOnCheckedChangeListener { _, checked -> startStopChronometer(checked, chronometerOne) }

}

private fun formatTime(chronometer: Chronometer) {
    val time = SystemClock.elapsedRealtime() - chronometer.base
    val h = (time / 3600000).toInt()
    val m = (time - h * 3600000).toInt() / 60000
    val s = (time - h * 3600000 - m * 60000).toInt() / 1000
    val hh = if (h < 10) "0$h" else h.toString() + ""
    val mm = if (m < 10) "0$m" else m.toString() + ""
    val ss = if (s < 10) "0$s" else s.toString() + ""
    chronometer.text = "$hh:$mm:$ss"
}

private fun startStopChronometer(checked: Boolean, chronometer: Chronometer) {
    if (checked) {
        chronometer.base = SystemClock.elapsedRealtime()
        chronometer.start()
    } else {
        chronometer.stop()
    }
}

I cannot figure out to add countDown functionality to the existing count up chronometer though.

I would like to set the time to count down from by employing a com.google.android.material.timepicker.MaterialTimePicker to allow the user to pick an hour and minute amount.

I have done this with an onClickListener on the chronometer itself which displays the TimePicker dialog as shown here...

chronometerOne.setOnClickListener {
    val timePickerDialog = MaterialTimePicker
        .Builder()
        .setHour(0)
        .setMinute(0)
        .setTimeFormat(TimeFormat.CLOCK_24H)
        .build()
    timePickerDialog.show(supportFragmentManager, "chronometer_one_fragment_tag")
    timePickerDialog.addOnPositiveButtonClickListener { _ ->
        displayPickedTime(chronometerOne, timePickerDialog)
    }
}


private fun displayPickedTime(chronometer: Chronometer, timePickerDialog: MaterialTimePicker) {
    chronometer.isCountDown = true
    val hour: Int = timePickerDialog.hour
    val minute: Int = timePickerDialog.minute
    chronometer.base = SystemClock.elapsedRealtime() + ((hour * 3600000) + (minute * 60000))
    chronometer.start()
}

However my existing private fun formatTime(chronometer: Chronometer) {...} function wipes the selected count down time

need to check in formatTime function if the Chronometer is counting down and change my formatting accordingly, however I cannot out how to do this.

Is it possible to have one Chronometer count up and down?

or do i need to have two Chronometers to achieve my desired result?

0

There are 0 best solutions below