Созданы звуковые уведомления, создана room, AppDatabase, Workout.kt, WorkoutAdapter.kt, WorkoutDao.kt, MyApplication.kt, workout_item.kt

This commit is contained in:
2025-05-13 17:53:14 +03:00
parent a00d3b34b0
commit 4e267fae79
18 changed files with 283 additions and 38 deletions
+1
View File
@@ -3,6 +3,7 @@
xmlns:tools="http://schemas.android.com/tools">
<application
android:name=".MyApplication"
android:allowBackup="true"
android:dataExtractionRules="@xml/data_extraction_rules"
android:fullBackupContent="@xml/backup_rules"
+9
View File
@@ -0,0 +1,9 @@
package com.example.timert
import androidx.room.Database
import androidx.room.RoomDatabase
import com.example.timert.Workout
import com.example.timert.WorkoutDao
@Database(entities = [Workout::class], version = 1)
abstract class AppDatabase : RoomDatabase() {
abstract fun workoutDao(): WorkoutDao
}
+17
View File
@@ -0,0 +1,17 @@
package com.example.timert
import androidx.room.Entity
import androidx.room.PrimaryKey
@Entity(tableName = "workouts")
data class Workout(
@PrimaryKey(autoGenerate = true)
val id: Int = 0,
val name: String,
val numApproaches: Int,
val numExercises: Int,
val restBetweenExercises: Int,
val restBetweenApproaches: Int,
val exerciseDuration: Int,
val startTime: Long? = null,
val endTime: Long? = null
)
+27
View File
@@ -0,0 +1,27 @@
package com.example.timert
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.TextView
import androidx.recyclerview.widget.RecyclerView
class WorkoutAdapter(private val workouts: List<Workout>) : RecyclerView.Adapter<WorkoutAdapter.WorkoutViewHolder>() {
class WorkoutViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
val textViewName: TextView = itemView.findViewById(R.id.textViewName)
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): WorkoutViewHolder {
val itemView = LayoutInflater.from(parent.context)
.inflate(R.layout.workout_item, parent, false)
return WorkoutViewHolder(itemView)
}
override fun onBindViewHolder(holder: WorkoutViewHolder, position: Int) {
val currentItem = workouts[position]
holder.textViewName.text = currentItem.name
}
override fun getItemCount() = workouts.size
}
+22
View File
@@ -0,0 +1,22 @@
package com.example.timert
import androidx.room.Dao
import androidx.room.Insert
import androidx.room.OnConflictStrategy
import androidx.room.Query
import androidx.room.Update
@Dao
interface WorkoutDao {
@Insert(onConflict = OnConflictStrategy.IGNORE)
suspend fun insertWorkout(workout: Workout): Long
@Query("SELECT * FROM workouts")
suspend fun getAllWorkouts(): List<Workout>
@Query("SELECT * FROM workouts WHERE id = :workoutId")
suspend fun getWorkoutById(workoutId: Int): Workout?
@Update
suspend fun updateWorkout(workout: Workout)
}
+10 -13
View File
@@ -7,27 +7,24 @@ import androidx.activity.enableEdgeToEdge
import androidx.appcompat.app.AppCompatActivity
import androidx.core.view.ViewCompat
import androidx.core.view.WindowInsetsCompat
import androidx.lifecycle.ViewModelProvider
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.example.timert.data.adapter.ExerciseAdapter
import com.example.timert.data.viewModel.ExerciseViewModel
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
class History : AppCompatActivity() {
private lateinit var recyclerViewHistory: RecyclerView
private val coroutineScope = CoroutineScope(Dispatchers.IO)
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
enableEdgeToEdge()
setContentView(R.layout.activity_history)
recyclerViewHistory = findViewById(R.id.recyclerViewHistory)
recyclerViewHistory.layoutManager = LinearLayoutManager(this)
ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.main)) { v, insets ->
val systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars())
v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom)
insets
}
val button_on_main: Button = findViewById(R.id.btn_on_main)
button_on_main.setOnClickListener {
val intent = Intent(this, MainActivity::class.java)
startActivity(intent)
}
}
}
@@ -2,7 +2,7 @@ package com.example.timert
import android.content.Intent
import android.os.Bundle
import android.view.View
import android.util.Log
import android.widget.Button
import android.widget.Toast
import androidx.activity.enableEdgeToEdge
@@ -10,7 +10,11 @@ import androidx.appcompat.app.AppCompatActivity
import androidx.core.view.ViewCompat
import androidx.core.view.WindowInsetsCompat
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
enableEdgeToEdge()
@@ -50,9 +54,8 @@ class MainActivity : AppCompatActivity() {
//TODO: Intent для открытия Activity создания шаблона (форма 7)
val intent = Intent(this, History::class.java)
startActivity(intent)
}
// ---- ROOM TEST ----
}
}
}
@@ -0,0 +1,20 @@
package com.example.timert
import android.app.Application
import androidx.room.Room
import com.example.timert.AppDatabase
class MyApplication : Application() {
companion object {
lateinit var database: AppDatabase
}
override fun onCreate() {
super.onCreate()
database = Room.databaseBuilder(
applicationContext,
AppDatabase::class.java,
"workout_database"
).build()
}
}
+42 -9
View File
@@ -2,10 +2,9 @@ package com.example.timert
import android.app.AlertDialog
import android.content.Intent
import android.media.Image
import android.media.MediaPlayer
import android.os.Bundle
import android.os.CountDownTimer
import android.widget.Button
import android.widget.ImageButton
import android.widget.TextView
import androidx.activity.enableEdgeToEdge
@@ -28,6 +27,14 @@ class timer : AppCompatActivity() {
private var exerciseDuration = 45 // например, 45 секунд упражнение
private var currentTimer: CountDownTimer? = null
private var timeLeftInMillis: Long = 0
// Объявляем переменные для MediaPlayer
private var startWorkoutSound: MediaPlayer? = null
private var workSound: MediaPlayer? = null
private var startRestSound: MediaPlayer? = null
private var restSound: MediaPlayer? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
enableEdgeToEdge()
@@ -47,6 +54,12 @@ class timer : AppCompatActivity() {
restBetweenApproaches = intent.getIntExtra("restBetweenApproaches", restBetweenApproaches)
exerciseDuration = intent.getIntExtra("exerciseDuration", exerciseDuration)
// Инициализируем MediaPlayer
startWorkoutSound = MediaPlayer.create(this, R.raw.sound1)
workSound = MediaPlayer.create(this, R.raw.sound1)
startRestSound = MediaPlayer.create(this, R.raw.sound2)
restSound = MediaPlayer.create(this, R.raw.sound3)
startTraining()
val button: ImageButton = findViewById(R.id.stop)
@@ -106,15 +119,18 @@ class timer : AppCompatActivity() {
statusText.text = "Тренировка завершена!"
rootLayout.setBackgroundResource(R.drawable.blue_gradient)
timerText.text = "00:00"
// Здесь должен быть звук завершения тренировки, если нужно
return
}
statusSet.text = "Подход № $currentApproach"
var currentExercise = 1
fun nextExercise() {
if (currentExercise > numExercises) {
statusText.text = "Отдых между подходами"
rootLayout.setBackgroundResource(R.drawable.green_gradient)
// Звук перед началом отдыха между подходами
startRestSound?.start()
startRest(restBetweenApproaches) {
currentApproach++
nextApproach()
@@ -122,23 +138,28 @@ class timer : AppCompatActivity() {
return
}
rootLayout.setBackgroundResource(R.drawable.gradient_pink)
statusText.text="Работа"
statusText.text = "Работа"
statusExercise.text = "$currentExercise / $numExercises"
statusSet.text="$currentApproach"
statusSet.text = "$currentApproach"
// Звук перед началом упражнения
workSound?.start()
startTimer(exerciseDuration) {
statusText.text = "Отдых"
rootLayout.setBackgroundResource(R.drawable.green_gradient)
// Звук перед началом отдыха между упражнениями
restSound?.start()
startRest(restBetweenExercises) {
currentExercise++
nextExercise()
}
}
}
// Звук перед началом подхода
startWorkoutSound?.start()
nextExercise()
}
nextApproach()
}
@@ -162,7 +183,6 @@ class timer : AppCompatActivity() {
override fun onTick(millisUntilFinished: Long) {
timerText.text = "${millisUntilFinished / 1000}"
statusText.text = "Отдых"
}
override fun onFinish() {
@@ -170,5 +190,18 @@ class timer : AppCompatActivity() {
}
}.start()
}
override fun onDestroy() {
super.onDestroy()
currentTimer?.cancel()
// Освобождаем ресурсы MediaPlayer
startWorkoutSound?.release()
workSound?.release()
startRestSound?.release()
restSound?.release()
startWorkoutSound = null
workSound = null
startRestSound = null
restSound = null
}
}
@@ -8,6 +8,15 @@
android:background="@drawable/gradient_purpure"
tools:context=".History">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recyclerViewHistory"
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent" />
<TextView
android:id="@+id/textView4"
android:layout_width="match_parent"
+17
View File
@@ -0,0 +1,17 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.cardview.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="8dp"
app:cardCornerRadius="4dp">
<TextView
android:id="@+id/textViewName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="16dp"
android:text="Workout Name"
android:textSize="18sp" />
</androidx.cardview.widget.CardView>
Binary file not shown.
Binary file not shown.
Binary file not shown.