I am trying to create a tabata timer. I managed to take the user input from an editText and to start one timer, which represents the preparation time.
When that preparation time is over I want to start the work time and then the resting time. Later on I need to repeat the Worktime and Resttime for x times as the user gives the input. But I am not able to figure it out.
MainActivity.kt:
btn_Start_Timer.setOnClickListener() {
val prepTimeMillis = Integer.parseInt(eT_PrepTime.text.toString().trim()) * 1000L;
val workTimeMillis = Integer.parseInt(eT_PrepTime.text.toString().trim()) * 1000L;
val restTimeMillis = Integer.parseInt(eT_PrepTime.text.toString().trim()) * 1000L;
val numberOfRepetitions = Integer.parseInt(eT_Number_Repetitions.text.toString().trim());
val Timer = object : CountDownTimer(prepTimeMillis, 1000) {
override fun onTick(millisUntilFinished: Long) {
tV_Total_Duration.setText("Preparation 00:00: " + millisUntilFinished / 1000)
}
override fun onFinish() {
tV_Total_Duration.setText("Preparation done!")
}
}
timer.start()
}
XML:
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<ScrollView
android:layout_width="0dp"
android:layout_height="0dp"
android:fillViewport="true"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:id="@+id/tV_Workout_Name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:editable="false"
android:text="Name of the Workout"
android:textSize="18sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/tV_Total_Repetitions" />
<EditText
android:id="@+id/eT_WorkoutName"
android:layout_width="290dp"
android:layout_height="40dp"
android:layout_marginTop="16dp"
android:ems="10"
android:inputType="textPersonName"
android:text="Name"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.495"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/tV_Workout_Name" />
<TextView
android:id="@+id/tV_Prepare"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:editable="false"
android:text="Preparation"
android:textSize="18sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/eT_WorkoutName" />
<EditText
android:id="@+id/eT_PrepTime"
android:layout_width="290dp"
android:layout_height="40dp"
android:layout_marginTop="16dp"
android:ems="10"
android:inputType="number"
android:text="0"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/tV_Prepare" />
<Button
android:id="@+id/btn_Decrement_PrepTime"
android:layout_width="50dp"
android:layout_height="40dp"
android:layout_marginTop="56dp"
android:text="-"
app:layout_constraintEnd_toStartOf="@+id/eT_PrepTime"
app:layout_constraintTop_toBottomOf="@+id/eT_WorkoutName" />
<Button
android:id="@+id/btn_Increment_PrepTime"
android:layout_width="50dp"
android:layout_height="40dp"
android:layout_marginTop="56dp"
android:text="+"
app:layout_constraintStart_toEndOf="@+id/eT_PrepTime"
app:layout_constraintTop_toBottomOf="@+id/eT_WorkoutName" />
<TextView
android:id="@+id/tV_WorkTime"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:editable="false"
android:text="Working"
android:textSize="18sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/eT_PrepTime" />
<EditText
android:id="@+id/eT_Work_Time"
android:layout_width="290dp"
android:layout_height="40dp"
android:layout_marginTop="16dp"
android:ems="10"
android:text="0"
android:inputType="number"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/tV_WorkTime" />
<Button
android:id="@+id/btn_Decrement_WorkTime"
android:layout_width="50dp"
android:layout_height="40dp"
android:layout_marginTop="56dp"
android:text="-"
app:layout_constraintEnd_toStartOf="@+id/eT_Work_Time"
app:layout_constraintTop_toBottomOf="@+id/btn_Decrement_PrepTime" />
<Button
android:id="@+id/btn_Increment_WorkTime"
android:layout_width="50dp"
android:layout_height="40dp"
android:layout_marginTop="56dp"
android:text="+"
app:layout_constraintStart_toEndOf="@+id/eT_Work_Time"
app:layout_constraintTop_toBottomOf="@+id/btn_Increment_PrepTime" />
<TextView
android:id="@+id/tv_Repetitions"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:editable="false"
android:text="Number of Repetitions"
android:textSize="18sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/eT_Rest_Time" />
<Button
android:id="@+id/btn_Decrement_Repetitions"
android:layout_width="50dp"
android:layout_height="40dp"
android:layout_marginTop="56dp"
android:text="-"
app:layout_constraintEnd_toStartOf="@+id/eT_Number_Repetitions"
app:layout_constraintTop_toBottomOf="@+id/btn_Decrement_Rest" />
<Button
android:id="@+id/btn_Increment_Repetitions"
android:layout_width="50dp"
android:layout_height="40dp"
android:layout_marginTop="56dp"
android:text="+"
app:layout_constraintStart_toEndOf="@+id/eT_Number_Repetitions"
app:layout_constraintTop_toBottomOf="@+id/btn_Increment_Rest" />
<EditText
android:id="@+id/eT_Number_Repetitions"
android:layout_width="290dp"
android:layout_height="40dp"
android:layout_marginTop="16dp"
android:ems="10"
android:inputType="number"
android:text="1"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.495"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/tv_Repetitions" />
<TextView
android:id="@+id/tV_Rest_Time"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:editable="false"
android:text="Resting"
android:textSize="18sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/eT_Work_Time" />
<Button
android:id="@+id/btn_Decrement_Rest"
android:layout_width="50dp"
android:layout_height="40dp"
android:layout_marginTop="56dp"
android:text="-"
app:layout_constraintEnd_toStartOf="@+id/eT_Rest_Time"
app:layout_constraintTop_toBottomOf="@+id/btn_Decrement_WorkTime" />
<EditText
android:id="@+id/eT_Rest_Time"
android:layout_width="290dp"
android:layout_height="40dp"
android:layout_marginTop="16dp"
android:ems="10"
android:text="0"
android:inputType="number"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.495"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/tV_Rest_Time" />
<Button
android:id="@+id/btn_Increment_Rest"
android:layout_width="50dp"
android:layout_height="40dp"
android:layout_marginTop="56dp"
android:text="+"
app:layout_constraintStart_toEndOf="@+id/eT_Rest_Time"
app:layout_constraintTop_toBottomOf="@+id/btn_Increment_WorkTime" />
<TextView
android:id="@+id/tV_Total_Duration"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:editable="false"
android:text="Duration 00:00:00"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/tV_Total_Repetitions"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:editable="false"
android:text="Repeated for x times"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/tV_Total_Duration" />
<Button
android:id="@+id/btn_Start_Timer"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="52dp"
android:layout_marginEnd="110dp"
android:layout_marginBottom="52dp"
android:text="Start now"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/eT_Number_Repetitions" />
<Button
android:id="@+id/btn_Stop_Timer"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="110dp"
android:layout_marginTop="52dp"
android:layout_marginBottom="52dp"
android:text="STOP"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/eT_Number_Repetitions" />
</androidx.constraintlayout.widget.ConstraintLayout>
</ScrollView>
</androidx.constraintlayout.widget.ConstraintLayout>
EDIT:
I managed to import the library.
But I get the following errors now:
Suspend function 'countDown' should be called only from a coroutine or another suspend function
Unresolved reference: lifecycleScope
Cannot inline bytecode built with JVM target 1.8 into bytecode that is being built with JVM target 1.6. Please specify proper 'jvm-target' option
No value passed for parameter 'handler'
Code:
btn_Start_Timer.setOnClickListener() {
val prepTimeMillis = Integer.parseInt(eT_PrepTime.text.toString().trim()) * 1000L;
val workTimeMillis = Integer.parseInt(eT_Work_Time.text.toString().trim()) * 1000L;
val restTimeMillis = Integer.parseInt(eT_Rest_Time.text.toString().trim()) * 1000L;
val numberOfRepetitions = Integer.parseInt(eT_Number_Repetitions.text.toString().trim());
countdownJob = lifecycleScope.launch {
repeat(numberOfRepetitions) {
countDown(prepTimeMillis, 1000L) { millisUntilFinished ->
tV_Total_Duration.setText("Preparation 00:00: " + millisUntilFinished / 1000)
}
countDown(workTimeMillis, 1000L) { millisUntilFinished ->
tV_Total_Duration.setText("Work 00:00: " + millisUntilFinished / 1000)
}
countDown(restTimeMillis, 1000L) { millisUntilFinished ->
tV_Total_Duration.setText("Rest 00:00: " + millisUntilFinished / 1000)
}
}
}
}
btn_Stop_Timer.setOnClickListener(){
}
}
suspend inline fun countDown(millisInFuture: Long, countDownInterval: Long, crossinline onTick: (Long) -> Unit) = withContext(Dispatchers.Main)
{
suspendCancellableCoroutine<Unit>
{ continuation ->
val timer = object: CountDownTimer(millisInFuture, countDownInterval)
{
override fun onTick(millisUntilFinished: Long) = onTick(millisUntilFinished)
override fun onFinish() = continuation.resume(Unit)
}.start()
continuation.invokeOnCancellation()
{
timer.cancel()
}
}
}
EDIT: build.gradle (Module.app):
apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-android-extensions'
android {
compileSdkVersion 29
buildToolsVersion "29.0.3"
defaultConfig {
applicationId "com.example.instafollow"
minSdkVersion 24
targetSdkVersion 29
versionCode 1
versionName "1.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
implementation("androidx.lifecycle:lifecycle-viewmodel:2.4.0-rc01")
implementation("androidx.lifecycle:lifecycle-livedata:2.4.0-rc01")
implementation("androidx.lifecycle:lifecycle-runtime:2.4.0-rc01")
implementation("androidx.lifecycle:lifecycle-viewmodel-savedstate:2.4.0-rc01")
annotationProcessor("androidx.lifecycle:lifecycle-compiler:2.4.0-rc01")
implementation("androidx.lifecycle:lifecycle-common-java8:2.4.0-rc01")
implementation("androidx.lifecycle:lifecycle-service:2.4.0-rc01")
implementation("androidx.lifecycle:lifecycle-process:2.4.0-rc01")
implementation("androidx.lifecycle:lifecycle-reactivestreams:2.4.0-rc01")
testImplementation("androidx.arch.core:core-testing:2.1.0")
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
implementation 'androidx.appcompat:appcompat:1.2.0'
implementation 'androidx.core:core-ktx:1.3.2'
implementation 'androidx.constraintlayout:constraintlayout:2.0.4'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'androidx.test.ext:junit:1.1.2'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0'
implementation 'com.google.android.material:material:1.4.0'
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.5.2'
}
build.gradle(project)
// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {
ext.kotlin_version = '1.3.72'
repositories {
google()
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:3.6.3'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}
}
allprojects {
repositories {
google()
jcenter()
}
}
task clean(type: Delete) {
delete rootProject.buildDir
}
EDIT:
I managed to change the target JVM to 1.8, and I have no more errors in my code. But when I try to start the project, I Get a series of errors like this: