Compare commits

...

16 Commits
main ... main

Author SHA1 Message Date
57f305819a добавление открытия созданных тренировок 2025-05-15 00:41:41 +03:00
3078443367 добавление данных тренировок и упражнений 2025-05-14 22:11:42 +03:00
505f533f04 Merge pull request 'Созданы звуковые уведомления, создана room, AppDatabase, Workout.kt, WorkoutAdapter.kt, WorkoutDao.kt, MyApplication.kt, workout_item.kt' (#3) from stud179289/Timer:Novikov_features into main
Reviewed-on: stud179277/Timer#3
2025-05-13 15:51:37 +00:00
4e267fae79 Созданы звуковые уведомления, создана room, AppDatabase, Workout.kt, WorkoutAdapter.kt, WorkoutDao.kt, MyApplication.kt, workout_item.kt 2025-05-13 17:53:14 +03:00
a00d3b34b0 добавление упражнений для тренировки, отображение на форме 2025-05-12 17:25:07 +03:00
0745430fad Изменение главной формы 2025-05-09 13:05:24 +03:00
33629d9c80 Исправлена глвная форма 2025-05-09 12:57:33 +03:00
Емцова Надежда
41389dad90 Готовые формы 2025-05-04 20:52:14 +03:00
Емцова Надежда
7e82560aac Итоговые формы 2025-05-04 20:23:23 +03:00
Емцова Надежда
56d127fd3f Готовые формы и переходы между формами 2025-05-04 17:45:08 +03:00
5ebe213205 Merge pull request 'Создание 2 формы' (#2) from stud159646/Timer:main into main
Reviewed-on: stud179277/Timer#2
2025-05-03 17:25:48 +00:00
d2163fd034 Создание 2 формы 2025-05-03 20:11:18 +03:00
36ace631fe Merge pull request 'Добавлены формы 1 и 6' (#1) from stud179289/Timer:Novikov_feature into main
Reviewed-on: stud179277/Timer#1
2025-05-03 10:21:26 +00:00
20c1e7a178 Добавлены формы 1 и 6 2025-05-02 17:57:21 +03:00
a2709d0813 Создание формы для добавления тренировок 2025-05-01 17:06:59 +03:00
ca52cec700 Создание формы с таймером 2025-04-28 19:05:24 +03:00
93 changed files with 3163 additions and 17 deletions

3
.idea/.gitignore generated vendored Normal file
View File

@ -0,0 +1,3 @@
# Default ignored files
/shelf/
/workspace.xml

1
.idea/.name generated Normal file
View File

@ -0,0 +1 @@
TimerT

6
.idea/AndroidProjectSystem.xml generated Normal file
View File

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="AndroidProjectSystem">
<option name="providerId" value="com.android.tools.idea.GradleProjectSystem" />
</component>
</project>

6
.idea/compiler.xml generated Normal file
View File

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="CompilerConfiguration">
<bytecodeTargetLevel target="21" />
</component>
</project>

10
.idea/deploymentTargetSelector.xml generated Normal file
View File

@ -0,0 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="deploymentTargetSelector">
<selectionStates>
<SelectionState runConfigName="app">
<option name="selectionMode" value="DROPDOWN" />
</SelectionState>
</selectionStates>
</component>
</project>

19
.idea/gradle.xml generated Normal file
View File

@ -0,0 +1,19 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="GradleMigrationSettings" migrationVersion="1" />
<component name="GradleSettings">
<option name="linkedExternalProjectsSettings">
<GradleProjectSettings>
<option name="testRunner" value="CHOOSE_PER_TEST" />
<option name="externalProjectPath" value="$PROJECT_DIR$" />
<option name="gradleJvm" value="#GRADLE_LOCAL_JAVA_HOME" />
<option name="modules">
<set>
<option value="$PROJECT_DIR$" />
<option value="$PROJECT_DIR$/app" />
</set>
</option>
</GradleProjectSettings>
</option>
</component>
</project>

6
.idea/kotlinc.xml generated Normal file
View File

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="KotlinJpsPluginSettings">
<option name="version" value="2.0.21" />
</component>
</project>

10
.idea/migrations.xml generated Normal file
View File

@ -0,0 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectMigrations">
<option name="MigrateToGradleLocalJavaHome">
<set>
<option value="$PROJECT_DIR$" />
</set>
</option>
</component>
</project>

9
.idea/misc.xml generated Normal file
View File

@ -0,0 +1,9 @@
<project version="4">
<component name="ExternalStorageConfigurationManager" enabled="true" />
<component name="ProjectRootManager" version="2" languageLevel="JDK_21" default="true" project-jdk-name="jbr-21" project-jdk-type="JavaSDK">
<output url="file://$PROJECT_DIR$/build/classes" />
</component>
<component name="ProjectType">
<option name="id" value="Android" />
</component>
</project>

6
.idea/render.experimental.xml generated Normal file
View File

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="RenderSettings">
<option name="showDecorations" value="true" />
</component>
</project>

17
.idea/runConfigurations.xml generated Normal file
View File

@ -0,0 +1,17 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="RunConfigurationProducerService">
<option name="ignoredProducers">
<set>
<option value="com.intellij.execution.junit.AbstractAllInDirectoryConfigurationProducer" />
<option value="com.intellij.execution.junit.AllInPackageConfigurationProducer" />
<option value="com.intellij.execution.junit.PatternConfigurationProducer" />
<option value="com.intellij.execution.junit.TestInClassConfigurationProducer" />
<option value="com.intellij.execution.junit.UniqueIdConfigurationProducer" />
<option value="com.intellij.execution.junit.testDiscovery.JUnitTestDiscoveryConfigurationProducer" />
<option value="org.jetbrains.kotlin.idea.junit.KotlinJUnitRunConfigurationProducer" />
<option value="org.jetbrains.kotlin.idea.junit.KotlinPatternConfigurationProducer" />
</set>
</option>
</component>
</project>

6
.idea/vcs.xml generated Normal file
View File

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="$PROJECT_DIR$" vcs="Git" />
</component>
</project>

View File

@ -1,6 +1,8 @@
plugins { plugins {
alias(libs.plugins.android.application) alias(libs.plugins.android.application)
alias(libs.plugins.kotlin.android) alias(libs.plugins.kotlin.android)
id("org.jetbrains.kotlin.kapt")
id("androidx.room")
} }
android { android {
@ -33,6 +35,13 @@ android {
kotlinOptions { kotlinOptions {
jvmTarget = "11" jvmTarget = "11"
} }
buildFeatures {
//noinspection WrongGradleMethod
room {
schemaDirectory("$projectDir/schemas")
}
}
} }
dependencies { dependencies {
@ -45,4 +54,13 @@ dependencies {
testImplementation(libs.junit) testImplementation(libs.junit)
androidTestImplementation(libs.androidx.junit) androidTestImplementation(libs.androidx.junit)
androidTestImplementation(libs.androidx.espresso.core) androidTestImplementation(libs.androidx.espresso.core)
// Room dependencies
implementation("androidx.room:room-runtime:2.7.1") // Замените на вашу версию
implementation("androidx.room:room-ktx:2.7.1") // Замените на вашу версию
kapt("androidx.room:room-compiler:2.7.1") // Замените на вашу версию
// Lifecycle dependencies
implementation ("androidx.lifecycle:lifecycle-viewmodel-ktx:2.7.0") // Замените на вашу версию
implementation ("androidx.lifecycle:lifecycle-livedata-ktx:2.7.0") // Замените на вашу версию
} }

View File

@ -0,0 +1,77 @@
{
"formatVersion": 1,
"database": {
"version": 1,
"identityHash": "87cf8dcd07bc0b2c0a8d52dbb0eca913",
"entities": [
{
"tableName": "workouts",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `name` TEXT NOT NULL, `numApproaches` INTEGER NOT NULL, `numExercises` INTEGER NOT NULL, `restBetweenExercises` INTEGER NOT NULL, `restBetweenApproaches` INTEGER NOT NULL, `exerciseDuration` INTEGER NOT NULL, `startTime` INTEGER, `endTime` INTEGER)",
"fields": [
{
"fieldPath": "id",
"columnName": "id",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "name",
"columnName": "name",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "numApproaches",
"columnName": "numApproaches",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "numExercises",
"columnName": "numExercises",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "restBetweenExercises",
"columnName": "restBetweenExercises",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "restBetweenApproaches",
"columnName": "restBetweenApproaches",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "exerciseDuration",
"columnName": "exerciseDuration",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "startTime",
"columnName": "startTime",
"affinity": "INTEGER"
},
{
"fieldPath": "endTime",
"columnName": "endTime",
"affinity": "INTEGER"
}
],
"primaryKey": {
"autoGenerate": true,
"columnNames": [
"id"
]
}
}
],
"setupQueries": [
"CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)",
"INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, '87cf8dcd07bc0b2c0a8d52dbb0eca913')"
]
}
}

View File

@ -0,0 +1,67 @@
{
"formatVersion": 1,
"database": {
"version": 1,
"identityHash": "6ba5dfef7859cedba19af71b404c9e4f",
"entities": [
{
"tableName": "workouts",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `name` TEXT NOT NULL, `numApproaches` INTEGER NOT NULL, `numExercises` INTEGER NOT NULL, `restBetweenExercises` INTEGER NOT NULL, `restBetweenApproaches` INTEGER NOT NULL, `exerciseDuration` INTEGER NOT NULL)",
"fields": [
{
"fieldPath": "id",
"columnName": "id",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "name",
"columnName": "name",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "numApproaches",
"columnName": "numApproaches",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "numExercises",
"columnName": "numExercises",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "restBetweenExercises",
"columnName": "restBetweenExercises",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "restBetweenApproaches",
"columnName": "restBetweenApproaches",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "exerciseDuration",
"columnName": "exerciseDuration",
"affinity": "INTEGER",
"notNull": true
}
],
"primaryKey": {
"autoGenerate": true,
"columnNames": [
"id"
]
}
}
],
"setupQueries": [
"CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)",
"INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, '6ba5dfef7859cedba19af71b404c9e4f')"
]
}
}

View File

@ -3,6 +3,7 @@
xmlns:tools="http://schemas.android.com/tools"> xmlns:tools="http://schemas.android.com/tools">
<application <application
android:name=".MyApplication"
android:allowBackup="true" android:allowBackup="true"
android:dataExtractionRules="@xml/data_extraction_rules" android:dataExtractionRules="@xml/data_extraction_rules"
android:fullBackupContent="@xml/backup_rules" android:fullBackupContent="@xml/backup_rules"
@ -12,6 +13,24 @@
android:supportsRtl="true" android:supportsRtl="true"
android:theme="@style/Theme.TimerT" android:theme="@style/Theme.TimerT"
tools:targetApi="31"> tools:targetApi="31">
<activity
android:name=".History"
android:exported="false" />
<activity
android:name=".SettingsActivity"
android:exported="false" />
<activity
android:name=".CreatingTraining"
android:exported="false" />
<activity
android:name=".timer"
android:exported="false" />
<activity
android:name=".AllTraining"
android:exported="true" />
<activity
android:name=".AddWorkout"
android:exported="true" />
<activity <activity
android:name=".MainActivity" android:name=".MainActivity"
android:exported="true"> android:exported="true">

Binary file not shown.

After

Width:  |  Height:  |  Size: 42 KiB

View File

@ -0,0 +1,190 @@
package com.example.timert
import android.app.AlertDialog
import android.content.Intent
import android.os.Bundle
import android.widget.Button
import android.widget.EditText
import android.widget.ImageView
import android.widget.Toast
import androidx.activity.enableEdgeToEdge
import androidx.appcompat.app.AppCompatActivity
import androidx.core.view.ViewCompat
import androidx.core.view.WindowInsetsCompat
import androidx.lifecycle.ViewModelProvider
import com.example.timert.com.example.timert.data.entity.Workout
import com.example.timert.data.viewModel.WorkoutViewModel
class AddWorkout : AppCompatActivity() {
private var isSave = false
private lateinit var editWorkoutView: EditText
private lateinit var numWorkoutView: EditText
private lateinit var numRestWorkoutView: EditText
private lateinit var numRestSetsView: EditText
private lateinit var numSetsView: EditText
private lateinit var timeWorkoutView: EditText
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
enableEdgeToEdge()
setContentView(R.layout.activity_add_workout)
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 workoutViewModel = ViewModelProvider(
this,
ViewModelProvider.AndroidViewModelFactory.getInstance(application)
)[WorkoutViewModel::class.java]
val workoutId = intent.getIntExtra("workoutId", -1)
editWorkoutView = findViewById(R.id.name_training)
numWorkoutView = findViewById(R.id.num_exercise)
numRestWorkoutView = findViewById(R.id.rest_workout_all)
numRestSetsView = findViewById(R.id.rest_sets_all)
numSetsView = findViewById(R.id.numbers_of_sets_all)
timeWorkoutView = findViewById(R.id.time_work_all)
if (workoutId != -1) {
val viewModel = ViewModelProvider(
this,
ViewModelProvider.AndroidViewModelFactory.getInstance(application)
)[WorkoutViewModel::class.java]
viewModel.allWorkouts.observe(this) { workouts ->
val workout = workouts.find { it.id == workoutId }
if (workout != null) {
editWorkoutView.setText(workout.name)
numWorkoutView.setText(workout.numExercises.toString())
numRestWorkoutView.setText(workout.restBetweenExercises.toString())
numRestSetsView.setText(workout.restBetweenApproaches.toString())
numSetsView.setText(workout.numApproaches.toString())
timeWorkoutView.setText(workout.exerciseDuration.toString())
}
}
}
val buttonSaveAll: Button = findViewById(R.id.btn_save_all)
buttonSaveAll.setOnClickListener {
val workoutName = editWorkoutView.text.toString()
val numWorkoutText = numWorkoutView.text.toString()
val restWorkoutText = numRestWorkoutView.text.toString()
val restSetsText = numRestSetsView.text.toString()
val numSetsText = numSetsView.text.toString()
val timeWorkText = timeWorkoutView.text.toString()
if (workoutName.isBlank() || numSetsText.isBlank() || restSetsText.isBlank()||numWorkoutText.isBlank() || restWorkoutText.isBlank() || timeWorkText.isBlank()) {
Toast.makeText(this, "Заполните все поля", Toast.LENGTH_SHORT).show()
} else {
val numExercise = numWorkoutText.toIntOrNull()
val restExercise = restWorkoutText.toIntOrNull()
val numSets = numSetsText.toIntOrNull()
val restSets = restSetsText.toIntOrNull()
val timeWorkExercise = timeWorkText.toIntOrNull()
if (numSets == null || restSets == null || numExercise == null || restExercise == null || timeWorkExercise == null) {
Toast.makeText(this, "Неверный формат чисел", Toast.LENGTH_SHORT).show()
return@setOnClickListener
}
val newWorkout = Workout(
name = workoutName,
numApproaches = numSets,
numExercises = numExercise,
restBetweenExercises = restExercise,
restBetweenApproaches = restSets,
exerciseDuration = timeWorkExercise,
)
workoutViewModel.insert(newWorkout)
Toast.makeText(this, "Тренировка сохранена", Toast.LENGTH_SHORT).show()
isSave = true
}
}
val button_on_main_all: Button = findViewById(R.id.btn_on_main_all)
button_on_main_all.setOnClickListener {
if (isSave == false) {
AlertDialog.Builder(this)
.setTitle("Изменения не сохранены")
.setMessage("Продолжить без сохранения?")
.setPositiveButton("Да") { _, _ ->
val intent = Intent(this, MainActivity::class.java)
startActivity(intent)
}
.setNegativeButton("Нет") { dialog, _ ->
dialog.dismiss()
}
.show()
} else {
val intent = Intent(this, MainActivity::class.java)
startActivity(intent)
}
}
val button_add: Button = findViewById(R.id.add_workoutadd)
button_add.setOnClickListener {
val intent = Intent(this, CreatingTraining::class.java)
startActivity(intent)
}
val timeInputRestSetAll: EditText = findViewById(R.id.rest_sets_all)
val btnPlusTimeAll: ImageView = findViewById(R.id.add_res_set2)
val btnMinusTimeAll: ImageView = findViewById(R.id.del_res_set2)
val setsInputAll: EditText = findViewById(R.id.numbers_of_sets_all)
val btnPlusSetsAll: ImageView = findViewById(R.id.add_set3)
val btnMinusSetsAll: ImageView = findViewById(R.id.del_set3)
val timeInputRest: EditText = findViewById(R.id.rest_workout_all)
val btnPlusTimeWor: ImageView = findViewById(R.id.add_res)
val btnMinusTimeWor: ImageView = findViewById(R.id.del_res)
val timeWork: EditText = findViewById(R.id.time_work_all)
val Plus: ImageView = findViewById(R.id.add_set)
val Minus: ImageView = findViewById(R.id.del_set)
val numExer: EditText = findViewById(R.id.num_exercise)
val PlusExer: ImageView = findViewById(R.id.add_set4)
val MinusExer: ImageView = findViewById(R.id.del_set4)
setupPlusMinus(timeInputRestSetAll, btnPlusTimeAll, btnMinusTimeAll, minValue = 5, maxValue = 600)
setupPlusMinus(setsInputAll, btnPlusSetsAll, btnMinusSetsAll, minValue = 1, maxValue = 20)
setupPlusMinus(timeInputRest, btnPlusTimeWor, btnMinusTimeWor, minValue = 5, maxValue = 600)
setupPlusMinus(timeWork, Plus, Minus, minValue = 5, maxValue = 600)
setupPlusMinus(numExer, PlusExer, MinusExer, minValue = 1, maxValue = 50)
}
fun setupPlusMinus(
editText: EditText,
plus: ImageView,
minus: ImageView,
minValue: Int = 5,
maxValue: Int = 600
) {
plus.setOnClickListener {
val current = editText.text.toString().toIntOrNull() ?: minValue
val newValue = (current + 1).coerceAtMost(maxValue)
editText.setText(newValue.toString())
}
minus.setOnClickListener {
val current = editText.text.toString().toIntOrNull() ?: minValue
val newValue = (current - 1).coerceAtLeast(minValue)
editText.setText(newValue.toString())
}
}
}

View File

@ -0,0 +1,136 @@
package com.example.timert
import android.app.Activity
import android.app.AlertDialog
import android.content.Intent
import android.os.Bundle
import android.text.TextUtils
import android.widget.Button
import android.widget.EditText
import android.widget.ImageView
import android.widget.Toast
import androidx.activity.enableEdgeToEdge
import androidx.appcompat.app.AppCompatActivity
import androidx.core.view.ViewCompat
import androidx.core.view.WindowInsetsCompat
import androidx.lifecycle.ViewModelProvider
import com.example.timert.data.entity.Exercise
import com.example.timert.data.viewModel.ExerciseViewModel
class AllTraining : AppCompatActivity() {
private var isSave = false
private lateinit var editExerciseView: EditText
private lateinit var numExerciseView: EditText
private lateinit var numRestExerciseView: EditText
override fun onCreate(savedInstanceState: Bundle?) {
val exerciseViewModel = ViewModelProvider(
this,
ViewModelProvider.AndroidViewModelFactory.getInstance(application)
)[ExerciseViewModel::class.java]
super.onCreate(savedInstanceState)
enableEdgeToEdge()
setContentView(R.layout.activity_all_training)
editExerciseView = findViewById(R.id.name_training)
numExerciseView = findViewById(R.id.time_work)
numRestExerciseView = findViewById(R.id.rest_workout)
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 buttonSaveAll: Button = findViewById(R.id.btn_save_all_vse)
buttonSaveAll.setOnClickListener {
val exerciseName = editExerciseView.text.toString()
val numSetsText = numExerciseView.text.toString()
val restSetsText = numRestExerciseView.text.toString()
if (exerciseName.isBlank() || numSetsText.isBlank() || restSetsText.isBlank()) {
Toast.makeText(this, "Заполните все поля", Toast.LENGTH_SHORT).show()
} else {
val numSets = numSetsText.toIntOrNull()
val restSets = restSetsText.toIntOrNull()
if (numSets == null || restSets == null) {
Toast.makeText(this, "Неверный формат чисел", Toast.LENGTH_SHORT).show()
return@setOnClickListener
}
val newExercise = Exercise(
name_exercise = exerciseName,
num_sets = numSets,
rest_of_sets = restSets,
trainingId = 0
)
exerciseViewModel.insert(newExercise)
//exerciseViewModel.addUnsavedExercise(newExercise)
Toast.makeText(this, "Упражнение сохранено", Toast.LENGTH_SHORT).show()
isSave = true
finish()
}
}
val button_on_main_all: Button = findViewById(R.id.btn_on_main_all_vse)
button_on_main_all.setOnClickListener {
if (isSave == false) {
AlertDialog.Builder(this)
.setTitle("Изменения не сохранены")
.setMessage("Продолжить без сохранения?")
.setPositiveButton("Да") { _, _ ->
val intent = Intent(this, MainActivity::class.java)
startActivity(intent)
finish()
}
.setNegativeButton("Нет") { dialog, _ ->
dialog.dismiss()
}
.show()
} else {
val intent = Intent(this, MainActivity::class.java)
startActivity(intent)
}
}
val timeInputRest: EditText = findViewById(R.id.rest_workout)
val btnPlusTime: ImageView = findViewById(R.id.add_res)
val btnMinusTime: ImageView = findViewById(R.id.del_res)
val setsInput: EditText = findViewById(R.id.time_work)
val btnPlusSets: ImageView = findViewById(R.id.add_set)
val btnMinusSets: ImageView = findViewById(R.id.del_set)
setupPlusMinus(timeInputRest, btnPlusTime, btnMinusTime, minValue = 5, maxValue = 600)
setupPlusMinus(setsInput, btnPlusSets, btnMinusSets, minValue = 5, maxValue = 600)
}
companion object {
const val EXTRA_REPLY = "com.example.android.wordlistsql.REPLY"
}
fun setupPlusMinus(
editText: EditText,
plus: ImageView,
minus: ImageView,
minValue: Int = 5,
maxValue: Int = 600
) {
plus.setOnClickListener {
val current = editText.text.toString().toIntOrNull() ?: minValue
val newValue = (current + 1).coerceAtMost(maxValue)
editText.setText(newValue.toString())
}
minus.setOnClickListener {
val current = editText.text.toString().toIntOrNull() ?: minValue
val newValue = (current - 1).coerceAtLeast(minValue)
editText.setText(newValue.toString())
}
}
}

View File

@ -0,0 +1,180 @@
package com.example.timert
import android.app.AlertDialog
import android.content.Intent
import android.os.Bundle
import android.widget.Button
import android.widget.EditText
import android.widget.ImageButton
import android.widget.ImageView
import android.widget.Toast
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.lifecycle.lifecycleScope
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.example.timert.data.adapter.ExerciseAdapter
import com.example.timert.data.entity.Training
import com.example.timert.data.viewModel.ExerciseViewModel
import com.example.timert.data.viewModel.TrainingViewModel
import com.example.timert.data.viewModel.WorkoutViewModel
import kotlinx.coroutines.launch
class CreatingTraining : AppCompatActivity() {
private lateinit var viewModel: ExerciseViewModel
private lateinit var trainingViewModel: TrainingViewModel
private lateinit var name_training: EditText
private lateinit var numSets: EditText
private lateinit var restSets: EditText
private var isSave = false
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
enableEdgeToEdge()
setContentView(R.layout.activity_creating_training)
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
}
name_training = findViewById(R.id.name_training)
numSets = findViewById(R.id.numbers_of_sets)
restSets = findViewById(R.id.rest_sets)
val recyclerView = findViewById<RecyclerView>(R.id.exercise)
val buttonSave: Button = findViewById(R.id.btn_save)
viewModel = ViewModelProvider(this)[ExerciseViewModel::class.java]
trainingViewModel = ViewModelProvider(this)[TrainingViewModel::class.java]
val adapter = ExerciseAdapter { id ->
viewModel.deleteExerciseById(id)
}
recyclerView.adapter = adapter
recyclerView.layoutManager = LinearLayoutManager(this)
val type = intent.getStringExtra("type")
val trainingId = intent.getIntExtra("trainingId", -1)
if (trainingId != -1) {
// Загружаем тренировку по ID
trainingViewModel.getTrainingById(trainingId).observe(this) { training ->
name_training.setText(training.name)
numSets.setText(training.numSets.toString())
restSets.setText(training.restBetweenSets.toString())
}
if (type == "trainingWithExercises") {
// Загружаем упражнения только если тренировка с упражнениями
viewModel.getExercisesByTrainingId(trainingId).observe(this) { exercises ->
adapter.setExercises(exercises)
}
viewModel.unsavedExercises.observe(this) { exercises ->
adapter.setExercises(exercises)
}
} else {
adapter.setExercises(emptyList()) // у обычной тренировки нет упражнений
}
} else {
// Создание новой — поля пустые, список упражнений пустой
adapter.setExercises(emptyList())
}
buttonSave.setOnClickListener {
val name = name_training.text.toString()
val numS = numSets.text.toString()
val resS = restSets.text.toString()
if (name.isBlank() || numS.isBlank() || resS.isBlank()) {
Toast.makeText(this, "Заполните все поля", Toast.LENGTH_SHORT).show()
} else {
val sets = numS.toIntOrNull()
val rest = resS.toIntOrNull()
if (sets == null || rest == null) {
Toast.makeText(this, "Неверный формат чисел", Toast.LENGTH_SHORT).show()
return@setOnClickListener
}
val newTraining = Training(
name = name,
numSets = sets,
restBetweenSets = rest)
trainingViewModel.insertTrainingAndLinkExercises(newTraining)
Toast.makeText(this, "Тренировка сохранена", Toast.LENGTH_SHORT).show()
isSave = true
}
}
val btnPlusTime: ImageView = findViewById(R.id.add_res)
val btnMinusTime: ImageView = findViewById(R.id.del_res)
val btnPlusSets: ImageView = findViewById(R.id.add_set)
val btnMinusSets: ImageView = findViewById(R.id.del_set)
setupPlusMinus(restSets, btnPlusTime, btnMinusTime, minValue = 5, maxValue = 600)
setupPlusMinus(numSets, btnPlusSets, btnMinusSets, minValue = 1, maxValue = 20)
val button_on_main: Button = findViewById(R.id.btn_on_main)
button_on_main.setOnClickListener {
if(isSave==false){
AlertDialog.Builder(this)
.setTitle("Изменения не сохранены")
.setMessage("Продолжить без сохранения?")
.setPositiveButton("Да") { _, _ ->
val intent = Intent(this, MainActivity::class.java)
startActivity(intent)
}
.setNegativeButton("Нет") { dialog, _ ->
dialog.dismiss()
}
.show()
}else{
val intent = Intent(this, MainActivity::class.java)
startActivity(intent)
}
}
val button_add: Button = findViewById(R.id.add_workout)
button_add.setOnClickListener {
val intent = Intent(this, AllTraining::class.java)
startActivity(intent)
}
}
fun setupPlusMinus(
editText: EditText,
plus: ImageView,
minus: ImageView,
minValue: Int = 5,
maxValue: Int = 600
) {
plus.setOnClickListener {
val current = editText.text.toString().toIntOrNull() ?: minValue
val newValue = (current + 1).coerceAtMost(maxValue)
editText.setText(newValue.toString())
}
minus.setOnClickListener {
val current = editText.text.toString().toIntOrNull() ?: minValue
val newValue = (current - 1).coerceAtLeast(minValue)
editText.setText(newValue.toString())
}
}
}

View File

@ -0,0 +1,36 @@
package com.example.timert
import android.content.Intent
import android.os.Bundle
import android.widget.Button
import androidx.activity.enableEdgeToEdge
import androidx.appcompat.app.AppCompatActivity
import androidx.core.view.ViewCompat
import androidx.core.view.WindowInsetsCompat
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
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)
val button_on_main: Button = findViewById(R.id.btn_on_main)
button_on_main.setOnClickListener {
val intent = Intent(this, MainActivity::class.java)
startActivity(intent)
}
}
}

View File

@ -1,12 +1,28 @@
package com.example.timert package com.example.timert
import android.content.Intent
import android.os.Bundle import android.os.Bundle
import android.widget.Button
import android.widget.Toast
import androidx.activity.enableEdgeToEdge import androidx.activity.enableEdgeToEdge
import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.app.AppCompatActivity
import androidx.core.view.ViewCompat import androidx.core.view.ViewCompat
import androidx.core.view.WindowInsetsCompat import androidx.core.view.WindowInsetsCompat
import androidx.lifecycle.ViewModelProvider
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.example.timert.com.example.timert.data.adapter.WorkoutAdapter
import com.example.timert.data.TrainingItem
import com.example.timert.data.adapter.TrainingAdapter
import com.example.timert.data.viewModel.TrainingViewModel
import com.example.timert.data.viewModel.WorkoutViewModel
class MainActivity : AppCompatActivity() { class MainActivity : AppCompatActivity() {
private lateinit var adapter: TrainingAdapter
private lateinit var workoutViewModel: WorkoutViewModel
private lateinit var trainingViewModel: TrainingViewModel
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
enableEdgeToEdge() enableEdgeToEdge()
@ -16,5 +32,86 @@ class MainActivity : AppCompatActivity() {
v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom) v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom)
insets insets
} }
adapter = TrainingAdapter(
onDeleteWorkout = { id -> workoutViewModel.deleteWorkoutById(id) },
onDeleteTraining = { id -> trainingViewModel.deleteTrainingById(id) },
onWorkoutClick = { workout ->
val intent = Intent(this, AddWorkout::class.java)
intent.putExtra("workout_id", workout.id)
startActivity(intent)
},
onTrainingClick = { training ->
val intent = Intent(this, CreatingTraining::class.java)
intent.putExtra("training_id", training.id)
startActivity(intent)
}
)
val recyclerView = findViewById<RecyclerView>(R.id.workout)
recyclerView.layoutManager = LinearLayoutManager(this)
recyclerView.adapter = adapter
workoutViewModel = ViewModelProvider(this)[WorkoutViewModel::class.java]
trainingViewModel = ViewModelProvider(this)[TrainingViewModel::class.java]
// объединяем данные вручную
val combinedList = mutableListOf<TrainingItem>()
workoutViewModel.allWorkouts.observe(this) { workouts ->
combinedList.clear()
combinedList.addAll(workouts.map { TrainingItem.WorkoutItem(it) })
trainingViewModel.allTrainingsWithExercises.value?.let { trainings ->
combinedList.addAll(trainings.map { TrainingItem.TrainingWithExercisesItem(it) })
}
adapter.submitList(combinedList.toList())
}
trainingViewModel.allTrainingsWithExercises.observe(this) { trainings ->
combinedList.clear()
workoutViewModel.allWorkouts.value?.let { workouts ->
combinedList.addAll(workouts.map { TrainingItem.WorkoutItem(it) })
}
combinedList.addAll(trainings.map {TrainingItem.TrainingWithExercisesItem(it) })
adapter.submitList(combinedList.toList())
}
// Кнопки главной формы:
val settingsButton: Button = findViewById(R.id.settingsButton)
settingsButton.setOnClickListener {
val intent = Intent(this, SettingsActivity::class.java)
startActivity(intent)
}
val startTrainingButton: Button = findViewById(R.id.startTrainingButton)
startTrainingButton.setOnClickListener {
Toast.makeText(this, "Запуск тренировки!", Toast.LENGTH_SHORT).show() // Заглушка
//TODO: Intent для запуска Activity тренировки (форма 5)
val intent = Intent(this, timer::class.java)
startActivity(intent)
}
val templatesButton: Button = findViewById(R.id.templatesButton)
templatesButton.setOnClickListener {
//Toast.makeText(this, "Открытие шаблонов!", Toast.LENGTH_SHORT).show() // Заглушка
//TODO: Intent для открытия Activity шаблонов (форма 3)
val intent = Intent(this, AddWorkout::class.java)
startActivity(intent)
}
val newTemplateButton: Button = findViewById(R.id.newTemplateButton)
newTemplateButton.setOnClickListener {
//Toast.makeText(this, "Создание нового шаблона!", Toast.LENGTH_SHORT).show() // Заглушка
//TODO: Intent для открытия Activity создания шаблона (форма 7)
val intent = Intent(this, History::class.java)
startActivity(intent)
}
// ---- ROOM TEST ----
} }
} }

View File

@ -0,0 +1,20 @@
package com.example.timert
import android.app.Application
import androidx.room.Room
import com.example.timert.com.example.timert.data.database.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()
}
}

View File

@ -0,0 +1,45 @@
package com.example.timert
import android.content.Context
import android.content.Intent
import android.content.pm.PackageManager
import android.os.Bundle
import android.widget.Switch
import android.widget.TextView
import androidx.appcompat.app.AppCompatActivity
import androidx.appcompat.app.AppCompatDelegate
import android.widget.Button
import androidx.appcompat.app.AlertDialog
import androidx.core.text.HtmlCompat
class SettingsActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_settings2)
val developersButton: Button = findViewById(R.id.developersButton)
// Обработчик нажатия на кнопку "Разработчики"
developersButton.setOnClickListener {
AlertDialog.Builder(this)
.setTitle("Разработчики")
.setMessage(HtmlCompat.fromHtml(
"<p style='margin-left: 2em;'><b>Программу разработали:</b></p><br>" +
"<p style='margin-left: 2em;'>Емцова Надежда Александровна</p>" +
"<p style='margin-left: 2em;'>Новиков Николай Алексеевич</p>" +
"<p style='margin-left: 2em;'>Пискун Алёна Викторовна</p>",
HtmlCompat.FROM_HTML_MODE_LEGACY
))
.setPositiveButton("ОК", null)
.show()
}
val on_main: Button = findViewById(R.id.btn_on_main)
on_main.setOnClickListener {
val intent = Intent(this, MainActivity::class.java)
startActivity(intent)
}
}
}

View File

@ -0,0 +1,9 @@
package com.example.timert.data
import com.example.timert.com.example.timert.data.entity.Workout
import com.example.timert.data.entity.Training
sealed class TrainingItem {
data class WorkoutItem(val workout: Workout) : TrainingItem()
data class TrainingWithExercisesItem(val trainingWithExercise: trainingWithExercise) : TrainingItem()
}

View File

@ -0,0 +1,50 @@
package com.example.timert.data.adapter
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.ImageButton
import android.widget.TextView
import androidx.recyclerview.widget.RecyclerView
import com.example.timert.R
import com.example.timert.data.entity.Exercise
//class ExerciseAdapter internal constructor(context: Context):RecyclerView.Adapter<ExerciseAdapter.ExerciseViewHolder>(){
class ExerciseAdapter(
private val onDeleteClick: (Int) -> Unit
) : RecyclerView.Adapter<ExerciseAdapter.ExerciseViewHolder>() {
private var exerciseList: List<Exercise> = emptyList()
inner class ExerciseViewHolder(itemView: View):RecyclerView.ViewHolder(itemView){
val textViewExercise: TextView = itemView.findViewById(R.id.textView13)
val deleteButton: ImageButton = itemView.findViewById(R.id.deleteButton)
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ExerciseViewHolder {
val view = LayoutInflater.from(parent.context).inflate(R.layout.resyclerview_item, parent, false)
return ExerciseViewHolder(view)
}
override fun onBindViewHolder(holder: ExerciseViewHolder, position: Int) {
val exercise = exerciseList[position]
holder.textViewExercise.text =
"${exercise.name_exercise} — работа: ${exercise.num_sets} сек, отдых: ${exercise.rest_of_sets} сек"
holder.deleteButton.setOnClickListener {
onDeleteClick(exercise.id)
}
}
override fun getItemCount() = exerciseList.size
fun setExercises(exercises: List<Exercise>) {
this.exerciseList = exercises
notifyDataSetChanged()
}
}

View File

@ -0,0 +1,104 @@
package com.example.timert.data.adapter
import android.content.Intent
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.Button
import android.widget.ImageButton
import android.widget.TextView
import androidx.recyclerview.widget.DiffUtil
import androidx.recyclerview.widget.ListAdapter
import androidx.recyclerview.widget.RecyclerView
import com.example.timert.AddWorkout
import com.example.timert.CreatingTraining
import com.example.timert.R
import com.example.timert.com.example.timert.data.entity.Workout
import com.example.timert.data.TrainingItem
import com.example.timert.data.entity.Training
import com.example.timert.data.trainingWithExercise
class TrainingAdapter( private val onDeleteWorkout: (Int) -> Unit,
private val onDeleteTraining: (Int) -> Unit,
private val onWorkoutClick: (Workout) -> Unit,
private val onTrainingClick: (Training) -> Unit
) : ListAdapter<TrainingItem, RecyclerView.ViewHolder>(DiffCallback()) {
companion object {
private const val TYPE_WORKOUT = 0
private const val TYPE_TRAINING_WITH_EXERCISES = 1
}
override fun getItemViewType(position: Int): Int {
return when (getItem(position)) {
is TrainingItem.WorkoutItem -> TYPE_WORKOUT
is TrainingItem.TrainingWithExercisesItem -> TYPE_TRAINING_WITH_EXERCISES
}
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
val inflater = LayoutInflater.from(parent.context)
val view = inflater.inflate(R.layout.training_item_layout, parent, false) // один layout
return when (viewType) {
TYPE_WORKOUT -> WorkoutViewHolder(view, onDeleteWorkout, onWorkoutClick)
TYPE_TRAINING_WITH_EXERCISES -> TrainingViewHolder(view, onDeleteTraining, onTrainingClick)
else -> throw IllegalArgumentException("Invalid view type")
}
}
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
when (val item = getItem(position)) {
is TrainingItem.WorkoutItem -> (holder as WorkoutViewHolder).bind(item.workout)
is TrainingItem.TrainingWithExercisesItem -> (holder as TrainingViewHolder).bind(item.trainingWithExercise)
}
}
class WorkoutViewHolder(itemView: View, private val onDelete: (Int) -> Unit,
private val onClick: (Workout) -> Unit) :
RecyclerView.ViewHolder(itemView) {
fun bind(workout: Workout) {
itemView.findViewById<TextView>(R.id.training_text).text = workout.name
itemView.findViewById<ImageButton>(R.id.deleteButtonTraining).setOnClickListener {
onDelete(workout.id)
}
itemView.setOnClickListener {
val context = itemView.context
val intent = Intent(context, AddWorkout::class.java)
intent.putExtra("workoutId", workout.id)
context.startActivity(intent)
}
}
}
class TrainingViewHolder(itemView: View, private val onDelete: (Int) -> Unit,
private val onClick: (Training) -> Unit) :
RecyclerView.ViewHolder(itemView) {
fun bind(trainingWithExercise: trainingWithExercise) {
val training = trainingWithExercise.training
itemView.findViewById<TextView>(R.id.training_text).text = trainingWithExercise.training.name
itemView.findViewById<ImageButton>(R.id.deleteButtonTraining).setOnClickListener {
onDelete(trainingWithExercise.training.id)
}
itemView.setOnClickListener {
val context = itemView.context
val intent = Intent(context, CreatingTraining::class.java)
intent.putExtra("type", "trainingWithExercises")
intent.putExtra("trainingId", trainingWithExercise.training.id)
context.startActivity(intent)
}
}
}
class DiffCallback : DiffUtil.ItemCallback<TrainingItem>() {
override fun areItemsTheSame(oldItem: TrainingItem, newItem: TrainingItem): Boolean {
return oldItem == newItem
}
override fun areContentsTheSame(oldItem: TrainingItem, newItem: TrainingItem): Boolean {
return oldItem == newItem
}
}
}

View File

@ -0,0 +1,48 @@
package com.example.timert.com.example.timert.data.adapter
import android.content.Context
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.ImageButton
import android.widget.TextView
import androidx.recyclerview.widget.RecyclerView
import com.example.timert.R
import com.example.timert.com.example.timert.data.entity.Workout
class WorkoutAdapter internal constructor(private val onDeleteClick: (Int) -> Unit
) : RecyclerView.Adapter<WorkoutAdapter.WorkoutViewHolder>() {
private var workouts: List<Workout> = emptyList()
inner class WorkoutViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
val textViewName: TextView = itemView.findViewById(R.id.training_text)
val deleteButton: ImageButton = itemView.findViewById(R.id.deleteButtonTraining)
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): WorkoutViewHolder {
val itemView = LayoutInflater.from(parent.context)
.inflate(R.layout.training_item_layout, parent, false)
return WorkoutViewHolder(itemView)
}
override fun onBindViewHolder(holder: WorkoutViewHolder, position: Int) {
val currentItem = workouts[position]
holder.textViewName.text =
"${currentItem.name}"
holder.deleteButton.setOnClickListener {
onDeleteClick(currentItem.id)
}
}
override fun getItemCount() = workouts.size
fun setWorkouts(workouts: List<Workout>) {
this.workouts = workouts
notifyDataSetChanged()
}
}

View File

@ -0,0 +1,32 @@
package com.example.timert.data.dao
import androidx.lifecycle.LiveData
import androidx.room.Dao
import androidx.room.Delete
import androidx.room.Insert
import androidx.room.OnConflictStrategy
import androidx.room.Query
import androidx.room.Transaction
import com.example.timert.data.entity.Exercise
@Dao
interface ExerciseDao {
@Transaction
@Insert(onConflict = OnConflictStrategy.REPLACE)
suspend fun insert(exercise: Exercise)
@Query("SELECT * FROM exercise_table")
fun getExercise(): LiveData<List<Exercise>>
@Query("DELETE FROM exercise_table WHERE id = :id")
suspend fun deleteById(id: Int)
@Query("UPDATE exercise_table SET trainingId = :newTrainingId WHERE trainingId = 0")
suspend fun updateExercisesWithTrainingId(newTrainingId: Int)
@Query("SELECT * FROM exercise_table WHERE trainingId = :trainingId")
fun getExercisesByTrainingId(trainingId: Int): LiveData<List<Exercise>>
}

View File

@ -0,0 +1,44 @@
package com.example.timert.data.dao
import androidx.lifecycle.LiveData
import androidx.room.Dao
import androidx.room.Delete
import androidx.room.Insert
import androidx.room.OnConflictStrategy
import androidx.room.Query
import androidx.room.Transaction
import com.example.timert.data.entity.Training
import com.example.timert.data.trainingWithExercise
@Dao
interface TrainingDao {
@Insert(onConflict = OnConflictStrategy.REPLACE)
suspend fun insertTraining(training: Training) : Long
@Query("SELECT * FROM Training WHERE id = :trainingId")
fun getTrainingWithExercise(trainingId: Int): LiveData<trainingWithExercise>
@Delete
fun deleteTraining(training: Training)
@Query("SELECT * FROM training")
fun getAllTrainings(): LiveData<List<Training>>
@Query("DELETE FROM training WHERE id = :id")
suspend fun deleteById(id: Int)
@Query("SELECT * FROM training WHERE id = :trainingId")
fun getTrainingWithExercises(trainingId: Int): LiveData<trainingWithExercise>
@Transaction
@Query("SELECT * FROM training")
fun getAllTrainingsWithExercises(): LiveData<List<trainingWithExercise>>
@Transaction
@Query("SELECT * FROM training")
fun getTrainingsWithExercises(): LiveData<List<trainingWithExercise>>
@Query("SELECT * FROM training WHERE id = :id")
fun getTrainingById(id: Int): LiveData<Training>
}

View File

@ -0,0 +1,29 @@
package com.example.timert.com.example.timert.data.dao
import androidx.lifecycle.LiveData
import androidx.room.Dao
import androidx.room.Insert
import androidx.room.OnConflictStrategy
import androidx.room.Query
import androidx.room.Update
import com.example.timert.com.example.timert.data.entity.Workout
import com.example.timert.data.entity.Exercise
@Dao
interface WorkoutDao {
@Insert(onConflict = OnConflictStrategy.IGNORE)
suspend fun insertWorkout(workout: Workout): Long
@Query("SELECT * FROM workouts")
fun getAllWorkouts(): LiveData<List<Workout>>
@Query("SELECT * FROM workouts WHERE id = :workoutId")
suspend fun getWorkoutById(workoutId: Int): Workout?
@Update
suspend fun updateWorkout(workout: Workout)
@Query("DELETE FROM workouts WHERE id = :id")
suspend fun deleteById(id: Int)
}

View File

@ -0,0 +1,43 @@
package com.example.timert.com.example.timert.data.database
import android.content.Context
import androidx.room.Database
import androidx.room.Room
import androidx.room.RoomDatabase
import com.example.timert.com.example.timert.data.dao.WorkoutDao
import com.example.timert.com.example.timert.data.entity.Workout
import com.example.timert.data.dao.ExerciseDao
import com.example.timert.data.dao.TrainingDao
import com.example.timert.data.entity.Exercise
import com.example.timert.data.entity.Training
import kotlinx.coroutines.CoroutineScope
@Database(entities = [Workout::class, Exercise::class, Training::class], version = 3, exportSchema = false)
abstract class AppDatabase : RoomDatabase() {
abstract fun workoutDao(): WorkoutDao
abstract fun trainingDao(): TrainingDao
abstract fun exerciseDao(): ExerciseDao
companion object {
@Volatile
private var INSTANCE: AppDatabase? = null
fun getDatabase(context: Context): AppDatabase {
val tempInstance = INSTANCE
if (tempInstance != null) {
return tempInstance
}
synchronized(this) {
val instance = Room.databaseBuilder(
context.applicationContext,
AppDatabase::class.java,
"workout_database"
)
//.fallbackToDestructiveMigration()
.build()
INSTANCE = instance
return instance
}
}
}
}

View File

@ -0,0 +1,15 @@
package com.example.timert.data.entity
import androidx.room.Entity
import androidx.room.ForeignKey
import androidx.room.Index
import androidx.room.PrimaryKey
@Entity(tableName = "exercise_table",
indices = [Index("trainingId")])
data class Exercise(@PrimaryKey(autoGenerate = true) val id: Int = 0,
val name_exercise: String,
val num_sets: Int,
val rest_of_sets: Int,
val trainingId: Int = 0)

View File

@ -0,0 +1,12 @@
package com.example.timert.data.entity
import androidx.room.Entity
import androidx.room.PrimaryKey
@Entity(tableName = "training")
data class Training(
@PrimaryKey(autoGenerate = true) val id: Int = 0,
val name: String,
val numSets: Int,
val restBetweenSets: Int
)

View File

@ -0,0 +1,16 @@
package com.example.timert.com.example.timert.data.entity
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
)

View File

@ -0,0 +1,21 @@
package com.example.timert.data.repository
import androidx.lifecycle.LiveData
import com.example.timert.data.dao.ExerciseDao
import com.example.timert.data.entity.Exercise
class ExerciseRepository(private val exerciseDao:ExerciseDao){
val allExercise: LiveData<List<Exercise>> = exerciseDao.getExercise()
suspend fun insert(training: Exercise) {
exerciseDao.insert(training)
}
suspend fun deleteExerciseById(id: Int) {
exerciseDao.deleteById(id)
}
fun getExercisesByTrainingId(trainingId: Int): LiveData<List<Exercise>> {
return exerciseDao.getExercisesByTrainingId(trainingId)
}
}

View File

@ -0,0 +1,27 @@
package com.example.timert.data.repository
import androidx.lifecycle.LiveData
import com.example.timert.data.dao.TrainingDao
import com.example.timert.data.entity.Training
import com.example.timert.data.trainingWithExercise
class TrainingRepository(private val trainingDao: TrainingDao) {
val allTrainings: LiveData<List<Training>> = trainingDao.getAllTrainings()
val allTrainingsWithExercises: LiveData<List<trainingWithExercise>> = trainingDao.getTrainingsWithExercises()
suspend fun insert(training: Training): Long {
return trainingDao.insertTraining(training)
}
suspend fun delete(training: Training) = trainingDao.deleteTraining(training)
suspend fun deleteTrainingById(id: Int) {
trainingDao.deleteById(id)
}
fun getTrainingById(id: Int): LiveData<Training> {
return trainingDao.getTrainingById(id)
}
}

View File

@ -0,0 +1,17 @@
package com.example.timert.data.repository
import androidx.lifecycle.LiveData
import com.example.timert.com.example.timert.data.dao.WorkoutDao
import com.example.timert.com.example.timert.data.entity.Workout
class WorkoutRepository (private val workoutDao: WorkoutDao){
val allWorkout: LiveData<List<Workout>> = workoutDao.getAllWorkouts()
suspend fun insert(workout: Workout) {
workoutDao.insertWorkout(workout)
}
suspend fun deleteWorkoutById(id: Int) {
workoutDao.deleteById(id)
}
}

View File

@ -0,0 +1,16 @@
package com.example.timert.data
import androidx.lifecycle.LiveData
import androidx.room.Embedded
import androidx.room.Relation
import com.example.timert.data.entity.Exercise
import com.example.timert.data.entity.Training
data class trainingWithExercise (
@Embedded val training: Training,
@Relation(
parentColumn = "id",
entityColumn = "trainingId"
)
val exercises: List<Exercise>
)

View File

@ -0,0 +1,46 @@
package com.example.timert.data.viewModel
import android.app.Application
import androidx.lifecycle.AndroidViewModel
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.viewModelScope
import com.example.timert.com.example.timert.data.database.AppDatabase
import com.example.timert.data.entity.Exercise
import com.example.timert.data.repository.ExerciseRepository
import kotlinx.coroutines.launch
class ExerciseViewModel(application: Application):AndroidViewModel(application){
private val repository: ExerciseRepository
val allExercise: LiveData<List<Exercise>>
private val _unsavedExercises = MutableLiveData<List<Exercise>>(emptyList())
val unsavedExercises: LiveData<List<Exercise>> = _unsavedExercises
init{
val exercisesDao = AppDatabase.getDatabase(application).exerciseDao()
repository = ExerciseRepository(exercisesDao)
allExercise = repository.allExercise
}
fun insert(exercise: Exercise) = viewModelScope.launch {
repository.insert(exercise)
}
fun deleteExerciseById(id: Int) = viewModelScope.launch {
repository.deleteExerciseById(id)
}
fun getExercisesByTrainingId(trainingId: Int): LiveData<List<Exercise>> {
return repository.getExercisesByTrainingId(trainingId)
}
fun addUnsavedExercise(exercise: Exercise) {
_unsavedExercises.value = _unsavedExercises.value.orEmpty() + exercise
}
fun deleteUnsavedExerciseById(id: Int) {
_unsavedExercises.value = _unsavedExercises.value.orEmpty().filterNot { it.id == id }
}
fun clearUnsavedExercises() {
_unsavedExercises.value = emptyList()
}
}

View File

@ -0,0 +1,54 @@
package com.example.timert.data.viewModel
import android.app.Application
import androidx.lifecycle.AndroidViewModel
import androidx.lifecycle.LiveData
import androidx.lifecycle.viewModelScope
import com.example.timert.com.example.timert.data.database.AppDatabase
import com.example.timert.data.entity.Training
import com.example.timert.data.repository.TrainingRepository
import com.example.timert.data.trainingWithExercise
import kotlinx.coroutines.launch
class TrainingViewModel (application: Application): AndroidViewModel(application){
val allWorkouts: LiveData<List<Training>>
private val trainingDao = AppDatabase.getDatabase(application).trainingDao()
private val repository = TrainingRepository(trainingDao)
val allTrainings: LiveData<List<Training>> = repository.allTrainings
val allTrainingsWithExercises: LiveData<List<trainingWithExercise>> = repository.allTrainingsWithExercises
init{
val trainingDao = AppDatabase.getDatabase(application).trainingDao()
allWorkouts = repository.allTrainings
}
fun insert(training: Training) = viewModelScope.launch {
repository.insert(training)
}
fun deleteTrainingById(id: Int) = viewModelScope.launch {
repository.deleteTrainingById(id)
}
fun delete(training: Training) = viewModelScope.launch {
repository.delete(training)
}
fun getTrainingById(id: Int): LiveData<Training> {
return repository.getTrainingById(id)
}
fun insertTrainingAndLinkExercises(training: Training) {
viewModelScope.launch {
val newId = repository.insert(training) // возвращает id
// теперь обновляем trainingId в упражнениях
AppDatabase.getDatabase(getApplication()).exerciseDao()
.updateExercisesWithTrainingId(newId.toInt())
}
}
}

View File

@ -0,0 +1,28 @@
package com.example.timert.data.viewModel
import android.app.Application
import androidx.lifecycle.AndroidViewModel
import androidx.lifecycle.LiveData
import androidx.lifecycle.viewModelScope
import com.example.timert.com.example.timert.data.database.AppDatabase
import com.example.timert.com.example.timert.data.entity.Workout
import com.example.timert.data.repository.WorkoutRepository
import kotlinx.coroutines.launch
class WorkoutViewModel(application: Application):AndroidViewModel(application){
private val repository: WorkoutRepository
val allWorkouts: LiveData<List<Workout>>
init{
val workoutDao = AppDatabase.getDatabase(application).workoutDao()
repository = WorkoutRepository(workoutDao)
allWorkouts = repository.allWorkout
}
fun insert(workout: Workout) = viewModelScope.launch {
repository.insert(workout)
}
fun deleteWorkoutById(id: Int) = viewModelScope.launch {
repository.deleteWorkoutById(id)
}
}

View File

@ -0,0 +1,207 @@
package com.example.timert
import android.app.AlertDialog
import android.content.Intent
import android.media.MediaPlayer
import android.os.Bundle
import android.os.CountDownTimer
import android.widget.ImageButton
import android.widget.TextView
import androidx.activity.enableEdgeToEdge
import androidx.appcompat.app.AppCompatActivity
import androidx.constraintlayout.widget.ConstraintLayout
import androidx.core.view.ViewCompat
import androidx.core.view.WindowInsetsCompat
class timer : AppCompatActivity() {
private var isPlay = false
private lateinit var statusText: TextView
private lateinit var timerText: TextView
private lateinit var statusSet: TextView
private lateinit var statusExercise: TextView
private var numApproaches = 3
private var numExercises = 5
private var restBetweenExercises = 30
private var restBetweenApproaches = 60
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()
setContentView(R.layout.activity_timer)
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
}
statusText = findViewById(R.id.statusText)
timerText = findViewById(R.id.timerText)
statusSet = findViewById(R.id.number_set)
statusExercise = findViewById(R.id.num_exercise)
numApproaches = intent.getIntExtra("numApproaches", numApproaches)
numExercises = intent.getIntExtra("numExercises", numExercises)
restBetweenExercises = intent.getIntExtra("restBetweenExercises", restBetweenExercises)
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)
button.setOnClickListener {
AlertDialog.Builder(this)
.setTitle("Сброс таймера")
.setMessage("Закрыть таймер и перейти на главную страницу?")
.setPositiveButton("Да") { _, _ ->
val intent = Intent(this, MainActivity::class.java)
startActivity(intent)
}
.setNegativeButton("Нет") { dialog, _ ->
dialog.dismiss()
}
.show()
}
val pauseButton: ImageButton = findViewById(R.id.play)
pauseButton.setOnClickListener {
if (isPlay) {
pauseButton.setImageResource(R.drawable.icon_play)
// здесь ещё можно возобновить таймер
} else {
pauseButton.setImageResource(R.drawable.icon_pause)
// здесь можно остановить таймер
}
isPlay = !isPlay
}
}
private fun resumeTimer(onFinish: () -> Unit) {
currentTimer = object : CountDownTimer(timeLeftInMillis, 1000) {
override fun onTick(millisUntilFinished: Long) {
timeLeftInMillis = millisUntilFinished
timerText.text = "${millisUntilFinished / 1000}"
}
override fun onFinish() {
onFinish()
}
}.start()
}
private fun startTraining() {
var currentApproach = 1
val rootLayout = findViewById<ConstraintLayout>(R.id.main)
fun nextApproach() {
if (currentApproach > numApproaches) {
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()
}
return
}
rootLayout.setBackgroundResource(R.drawable.gradient_pink)
statusText.text = "Работа"
statusExercise.text = "$currentExercise / $numExercises"
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()
}
private fun startTimer(seconds: Int, onFinish: () -> Unit) {
timeLeftInMillis = seconds * 1000L
object : CountDownTimer(seconds * 1000L, 1000) {
override fun onTick(millisUntilFinished: Long) {
timerText.text = "${millisUntilFinished / 1000}"
}
override fun onFinish() {
onFinish()
}
}.start()
}
private fun startRest(seconds: Int, onFinish: () -> Unit) {
val rootLayout = findViewById<ConstraintLayout>(R.id.main)
rootLayout.setBackgroundResource(R.drawable.green_gradient)
object : CountDownTimer(seconds * 1000L, 1000) {
override fun onTick(millisUntilFinished: Long) {
timerText.text = "${millisUntilFinished / 1000}"
statusText.text = "Отдых"
}
override fun onFinish() {
onFinish()
}
}.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
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 MiB

View File

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<shape
xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<gradient
android:startColor="@color/colorGradientBlueStart"
android:endColor="@color/colorGradientBlueStop"
android:angle="270" />
</shape>

View File

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<shape
xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<gradient
android:startColor="@color/colorGradientPinkStart"
android:endColor="@color/colorGradientPinkStop"
android:angle="270" />
</shape>

View File

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<shape
xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<gradient
android:startColor="@color/colorGradientPurpureStart"
android:endColor="@color/colorGradientPurpureStop"
android:angle="180" />
</shape>

View File

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<shape
xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<gradient
android:startColor="@color/colorGradientGreenStart"
android:endColor="@color/colorGradientGreenStop"
android:angle="270" />
</shape>

View File

@ -0,0 +1,14 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<gradient
android:type="linear"
android:startColor="@color/colorGradientGreenStart"
android:endColor="@color/colorGradientGreenStop"
android:gradientRadius="90" />
<corners android:radius="10dp"/>
</shape>

View File

@ -0,0 +1,10 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24"
android:tint="?attr/colorControlNormal">
<path
android:fillColor="@android:color/white"
android:pathData="M19,13h-6v6h-2v-6H5v-2h6V5h2v6h6v2z"/>
</vector>

View File

@ -0,0 +1,10 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24"
android:tint="?attr/colorControlNormal">
<path
android:fillColor="@android:color/white"
android:pathData="M19,13H5v-2h14v2z"/>
</vector>

View File

@ -0,0 +1,5 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android" android:height="24dp" android:tint="#3D6ADC" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp">
<path android:fillColor="@android:color/white" android:pathData="M19.14,12.94c0.04,-0.3 0.06,-0.61 0.06,-0.94c0,-0.32 -0.02,-0.64 -0.07,-0.94l2.03,-1.58c0.18,-0.14 0.23,-0.41 0.12,-0.61l-1.92,-3.32c-0.12,-0.22 -0.37,-0.29 -0.59,-0.22l-2.39,0.96c-0.5,-0.38 -1.03,-0.7 -1.62,-0.94L14.4,2.81c-0.04,-0.24 -0.24,-0.41 -0.48,-0.41h-3.84c-0.24,0 -0.43,0.17 -0.47,0.41L9.25,5.35C8.66,5.59 8.12,5.92 7.63,6.29L5.24,5.33c-0.22,-0.08 -0.47,0 -0.59,0.22L2.74,8.87C2.62,9.08 2.66,9.34 2.86,9.48l2.03,1.58C4.84,11.36 4.8,11.69 4.8,12s0.02,0.64 0.07,0.94l-2.03,1.58c-0.18,0.14 -0.23,0.41 -0.12,0.61l1.92,3.32c0.12,0.22 0.37,0.29 0.59,0.22l2.39,-0.96c0.5,0.38 1.03,0.7 1.62,0.94l0.36,2.54c0.05,0.24 0.24,0.41 0.48,0.41h3.84c0.24,0 0.44,-0.17 0.47,-0.41l0.36,-2.54c0.59,-0.24 1.13,-0.56 1.62,-0.94l2.39,0.96c0.22,0.08 0.47,0 0.59,-0.22l1.92,-3.32c0.12,-0.22 0.07,-0.47 -0.12,-0.61L19.14,12.94zM12,15.6c-1.98,0 -3.6,-1.62 -3.6,-3.6s1.62,-3.6 3.6,-3.6s3.6,1.62 3.6,3.6S13.98,15.6 12,15.6z"/>
</vector>

View File

@ -0,0 +1,10 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24"
android:tint="?attr/colorControlNormal">
<path
android:fillColor="@android:color/white"
android:pathData="M6,19h4L10,5L6,5v14zM14,5v14h4L18,5h-4z"/>
</vector>

View File

@ -0,0 +1,10 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24"
android:tint="?attr/colorControlNormal">
<path
android:fillColor="@android:color/white"
android:pathData="M8,5v14l11,-7z"/>
</vector>

View File

@ -0,0 +1,10 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24"
android:tint="?attr/colorControlNormal">
<path
android:fillColor="@android:color/white"
android:pathData="M6,6h12v12H6z"/>
</vector>

View File

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<shape
xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<gradient
android:startColor="@color/colorGradientPinkStart"
android:endColor="@color/colorGradientPinkStop"
android:angle="270" />
</shape>

View File

@ -0,0 +1,335 @@
<?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:id="@+id/main"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@drawable/blue_gradient"
tools:context=".AddWorkout">
<LinearLayout
android:id="@+id/linearLayout"
android:layout_width="match_parent"
android:layout_height="130dp"
android:layout_marginTop="25dp"
android:orientation="vertical"
app:layout_constraintTop_toTopOf="parent">
<TextView
android:id="@+id/textView2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Тренировка"
android:textAlignment="center"
android:textSize="34sp" />
<EditText
android:id="@+id/name_training"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="20dp"
android:ems="10"
android:inputType="text"
android:text="Моя тренировка"
android:textAlignment="center"
android:textSize="20sp" />
</LinearLayout>
<ScrollView
android:id="@+id/scrollView2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
app:layout_constraintBottom_toTopOf="@+id/frameLayout2"
app:layout_constraintTop_toBottomOf="@+id/linearLayout"
tools:layout_editor_absoluteX="9dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<LinearLayout
android:id="@+id/setting_training"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="10dp"
android:orientation="vertical">
<TextView
android:id="@+id/textView6"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Количество подходов"
android:textAlignment="center"
android:textSize="24sp" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="60dp"
android:orientation="horizontal">
<ImageView
android:id="@+id/del_set3"
android:layout_width="wrap_content"
android:layout_height="37dp"
android:layout_gravity="center"
android:layout_weight="1"
app:srcCompat="@drawable/ic_remove_24px" />
<EditText
android:id="@+id/numbers_of_sets_all"
android:layout_width="3dp"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_weight="1"
android:ems="10"
android:gravity="center"
android:inputType="number"
android:text="1"
android:textSize="26sp" />
<ImageView
android:id="@+id/add_set3"
android:layout_width="wrap_content"
android:layout_height="37dp"
android:layout_gravity="center"
android:layout_weight="1"
app:srcCompat="@drawable/ic_add_24px" />
</LinearLayout>
<TextView
android:id="@+id/textView14"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Количество упражнений"
android:textAlignment="center"
android:textSize="24sp" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal">
<ImageView
android:id="@+id/del_set4"
android:layout_width="wrap_content"
android:layout_height="37dp"
android:layout_gravity="center"
android:layout_weight="1"
app:srcCompat="@drawable/ic_remove_24px" />
<EditText
android:id="@+id/num_exercise"
android:layout_width="3dp"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_weight="1"
android:ems="10"
android:gravity="center"
android:inputType="number"
android:text="1"
android:textSize="26sp" />
<ImageView
android:id="@+id/add_set4"
android:layout_width="wrap_content"
android:layout_height="37dp"
android:layout_gravity="center"
android:layout_weight="1"
app:srcCompat="@drawable/ic_add_24px" />
</LinearLayout>
<TextView
android:id="@+id/textView8_all2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Отдых между подходами"
android:textAlignment="center"
android:textSize="24sp" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<ImageView
android:id="@+id/del_res_set2"
android:layout_width="wrap_content"
android:layout_height="37dp"
android:layout_gravity="center"
android:layout_weight="1"
app:srcCompat="@drawable/ic_remove_24px" />
<EditText
android:id="@+id/rest_sets_all"
android:layout_width="3dp"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_weight="1"
android:ems="10"
android:gravity="center"
android:inputType="number"
android:text="5"
android:textSize="26sp" />
<ImageView
android:id="@+id/add_res_set2"
android:layout_width="wrap_content"
android:layout_height="37dp"
android:layout_gravity="center"
android:layout_weight="1"
app:srcCompat="@drawable/ic_add_24px" />
</LinearLayout>
<TextView
android:id="@+id/textView5"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Время работы"
android:textAlignment="center"
android:textSize="24sp" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="60dp"
android:layout_marginBottom="20dp"
android:orientation="horizontal">
<ImageView
android:id="@+id/del_set"
android:layout_width="wrap_content"
android:layout_height="37dp"
android:layout_gravity="center"
android:layout_weight="1"
app:srcCompat="@drawable/ic_remove_24px" />
<EditText
android:id="@+id/time_work_all"
android:layout_width="3dp"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_weight="1"
android:ems="10"
android:gravity="center"
android:inputType="number"
android:text="5"
android:textSize="26sp" />
<ImageView
android:id="@+id/add_set"
android:layout_width="wrap_content"
android:layout_height="37dp"
android:layout_gravity="center"
android:layout_weight="1"
app:srcCompat="@drawable/ic_add_24px" />
</LinearLayout>
<TextView
android:id="@+id/textView8_all"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Отдых между упражнениями"
android:textAlignment="center"
android:textSize="24sp" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="60dp"
android:orientation="horizontal">
<ImageView
android:id="@+id/del_res"
android:layout_width="wrap_content"
android:layout_height="37dp"
android:layout_gravity="center"
android:layout_weight="1"
app:srcCompat="@drawable/ic_remove_24px" />
<EditText
android:id="@+id/rest_workout_all"
android:layout_width="3dp"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_weight="1"
android:ems="10"
android:gravity="center"
android:inputType="number"
android:text="5"
android:textSize="26sp" />
<ImageView
android:id="@+id/add_res"
android:layout_width="wrap_content"
android:layout_height="37dp"
android:layout_gravity="center"
android:layout_weight="1"
app:srcCompat="@drawable/ic_add_24px" />
</LinearLayout>
</LinearLayout>
</LinearLayout>
</ScrollView>
<FrameLayout
android:id="@+id/frameLayout2"
android:layout_width="match_parent"
android:layout_height="60dp"
app:layout_constraintBottom_toTopOf="@+id/linearLayout4"
tools:layout_editor_absoluteX="0dp">
<Button
android:id="@+id/add_workoutadd"
android:layout_width="208dp"
android:layout_height="50dp"
android:layout_gravity="center"
android:background="@drawable/green_rectangle"
android:gravity="center"
android:text="Выбор упражнений"
android:textAlignment="center"
android:textColor="@color/white"
android:textSize="16sp" />
</FrameLayout>
<LinearLayout
android:id="@+id/linearLayout4"
android:layout_width="match_parent"
android:layout_height="60dp"
android:layout_marginBottom="8dp"
android:orientation="horizontal"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent">
<Button
android:id="@+id/btn_on_main_all"
android:layout_width="150dp"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginLeft="20dp"
android:layout_marginRight="20dp"
android:layout_weight="1"
android:background="@drawable/gradient_purpure"
android:text="на главную"
android:textAlignment="center"
android:textColor="@color/white" />
<Button
android:id="@+id/btn_save_all"
android:layout_width="150dp"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginLeft="20dp"
android:layout_marginRight="20dp"
android:layout_weight="1"
android:background="@drawable/gradient_purpure"
android:text="Сохранить"
android:textAlignment="center"
android:textColor="@color/white" />
</LinearLayout>
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@ -0,0 +1,174 @@
<?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:id="@+id/main"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@drawable/gradient_pink"
tools:context=".AllTraining">
<LinearLayout
android:id="@+id/linearLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="25dp"
android:orientation="vertical"
app:layout_constraintTop_toTopOf="parent">
<TextView
android:id="@+id/textView2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Добавить упражнение"
android:textAlignment="center"
android:textSize="34sp" />
<EditText
android:id="@+id/name_training"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="20dp"
android:ems="10"
android:inputType="text"
android:text="Упражнение"
android:textAlignment="center"
android:textSize="20sp" />
</LinearLayout>
<LinearLayout
android:id="@+id/setting_training"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="5dp"
android:orientation="vertical"
app:layout_constraintTop_toBottomOf="@+id/linearLayout"
tools:layout_editor_absoluteX="16dp">
<TextView
android:id="@+id/textView3"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Время работы, сек"
android:textAlignment="center"
android:textSize="24sp" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="20dp"
android:orientation="horizontal">
<ImageView
android:id="@+id/del_set"
android:layout_width="wrap_content"
android:layout_height="37dp"
android:layout_gravity="center"
android:layout_weight="1"
app:srcCompat="@drawable/ic_remove_24px" />
<EditText
android:id="@+id/time_work"
android:layout_width="3dp"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_weight="1"
android:ems="10"
android:gravity="center"
android:inputType="number"
android:text="5"
android:textSize="26sp" />
<ImageView
android:id="@+id/add_set"
android:layout_width="wrap_content"
android:layout_height="37dp"
android:layout_gravity="center"
android:layout_weight="1"
app:srcCompat="@drawable/ic_add_24px" />
</LinearLayout>
<TextView
android:id="@+id/textView8_all"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Отдых между упражнениями, сек"
android:textAlignment="center"
android:textSize="24sp" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<ImageView
android:id="@+id/del_res"
android:layout_width="wrap_content"
android:layout_height="37dp"
android:layout_gravity="center"
android:layout_weight="1"
app:srcCompat="@drawable/ic_remove_24px" />
<EditText
android:id="@+id/rest_workout"
android:layout_width="3dp"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_weight="1"
android:ems="10"
android:gravity="center"
android:inputType="number"
android:text="5"
android:textSize="26sp" />
<ImageView
android:id="@+id/add_res"
android:layout_width="wrap_content"
android:layout_height="37dp"
android:layout_gravity="center"
android:layout_weight="1"
app:srcCompat="@drawable/ic_add_24px" />
</LinearLayout>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="60dp"
android:layout_marginBottom="35dp"
android:orientation="horizontal"
app:layout_constraintBottom_toBottomOf="parent"
tools:layout_editor_absoluteX="7dp">
<Button
android:id="@+id/btn_on_main_all_vse"
android:layout_width="150dp"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginLeft="20dp"
android:layout_marginRight="20dp"
android:layout_weight="1"
android:background="@drawable/gradient_purpure"
android:text="на главную"
android:textAlignment="center"
android:textColor="@color/white"
tools:layout_editor_absoluteX="16dp"
tools:layout_editor_absoluteY="653dp" />
<Button
android:id="@+id/btn_save_all_vse"
android:layout_width="150dp"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginLeft="20dp"
android:layout_marginRight="20dp"
android:layout_weight="1"
android:background="@drawable/gradient_purpure"
android:text="Сохранить"
android:textAlignment="center"
android:textColor="@color/white"
tools:layout_editor_absoluteX="245dp"
tools:layout_editor_absoluteY="653dp" />
</LinearLayout>
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@ -0,0 +1,217 @@
<?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:id="@+id/main"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@drawable/blue_gradient"
tools:context=".CreatingTraining">
<LinearLayout
android:id="@+id/linearLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="25dp"
android:orientation="vertical"
app:layout_constraintTop_toTopOf="parent">
<TextView
android:id="@+id/textView2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Тренировка"
android:textAlignment="center"
android:textSize="34sp" />
<EditText
android:id="@+id/name_training"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:ems="10"
android:inputType="text"
android:text="Моя тренировка"
android:textAlignment="center"
android:textSize="20sp" />
</LinearLayout>
<LinearLayout
android:id="@+id/setting_training"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
app:layout_constraintBottom_toTopOf="@+id/exercise"
app:layout_constraintTop_toBottomOf="@+id/linearLayout">
<TextView
android:id="@+id/textView5"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Количество подходов"
android:textAlignment="center"
android:textSize="24sp" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="8dp"
android:orientation="horizontal">
<ImageView
android:id="@+id/del_set"
android:layout_width="wrap_content"
android:layout_height="37dp"
android:layout_gravity="center"
android:layout_weight="1"
app:srcCompat="@drawable/ic_remove_24px" />
<EditText
android:id="@+id/numbers_of_sets"
android:layout_width="3dp"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_weight="1"
android:ems="10"
android:gravity="center"
android:inputType="number"
android:text="1"
android:textSize="26sp" />
<ImageView
android:id="@+id/add_set"
android:layout_width="wrap_content"
android:layout_height="37dp"
android:layout_gravity="center"
android:layout_weight="1"
app:srcCompat="@drawable/ic_add_24px" />
</LinearLayout>
<TextView
android:id="@+id/textView8"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Отдых между подходами"
android:textAlignment="center"
android:textSize="24sp" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="8dp"
android:orientation="horizontal">
<ImageView
android:id="@+id/del_res"
android:layout_width="wrap_content"
android:layout_height="37dp"
android:layout_gravity="center"
android:layout_weight="1"
app:srcCompat="@drawable/ic_remove_24px" />
<EditText
android:id="@+id/rest_sets"
android:layout_width="3dp"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_weight="1"
android:ems="10"
android:gravity="center"
android:inputType="number"
android:text="5"
android:textSize="26sp" />
<ImageView
android:id="@+id/add_res"
android:layout_width="wrap_content"
android:layout_height="37dp"
android:layout_gravity="center"
android:layout_weight="1"
app:srcCompat="@drawable/ic_add_24px" />
</LinearLayout>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical" />
</LinearLayout>
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/exercise"
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintBottom_toTopOf="@+id/frameLayout"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.373"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/setting_training"
app:layout_constraintVertical_bias="0.178" />
<FrameLayout
android:id="@+id/frameLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintBottom_toTopOf="@+id/linearLayout2"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="1.0"
app:layout_constraintStart_toStartOf="parent">
<Button
android:id="@+id/add_workout"
android:layout_width="176dp"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginTop="10dp"
android:layout_marginBottom="10dp"
android:background="@drawable/green_rectangle"
android:gravity="center"
android:text="+ упражнение"
android:textAlignment="center"
android:textColor="@color/white"
android:textSize="16sp" />
</FrameLayout>
<LinearLayout
android:id="@+id/linearLayout2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toStartOf="parent">
<Button
android:id="@+id/btn_on_main"
android:layout_width="150dp"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginLeft="8dp"
android:layout_marginRight="8dp"
android:layout_weight="1"
android:background="@drawable/gradient_purpure"
android:text="на главную"
android:textAlignment="center"
android:textColor="@color/white" />
<Button
android:id="@+id/btn_save"
android:layout_width="150dp"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginLeft="8dp"
android:layout_marginRight="8dp"
android:layout_weight="1"
android:background="@drawable/gradient_purpure"
android:text="Сохранить"
android:textAlignment="center"
android:textColor="@color/white" />
</LinearLayout>
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@ -0,0 +1,66 @@
<?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:id="@+id/main"
android:layout_width="match_parent"
android:layout_height="match_parent"
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"
android:layout_height="wrap_content"
android:layout_marginTop="30dp"
android:text="История тренировок"
android:textAlignment="center"
android:textSize="34sp"
app:layout_constraintTop_toTopOf="parent" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="60dp"
android:layout_marginBottom="35dp"
android:orientation="horizontal"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent">
<Button
android:id="@+id/btn_on_main"
android:layout_width="150dp"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginLeft="20dp"
android:layout_marginRight="20dp"
android:layout_weight="1"
android:background="@drawable/green_gradient"
android:text="на главную"
android:textAlignment="center"
android:textColor="@color/white" />
<Button
android:id="@+id/btn_save"
android:layout_width="150dp"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginLeft="20dp"
android:layout_marginRight="20dp"
android:layout_weight="1"
android:background="@drawable/green_gradient"
android:text="Выбрать"
android:textAlignment="center"
android:textColor="@color/white" />
</LinearLayout>
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@ -7,13 +7,108 @@
android:layout_height="match_parent" android:layout_height="match_parent"
tools:context=".MainActivity"> tools:context=".MainActivity">
<TextView <ImageView
android:layout_width="wrap_content" android:id="@+id/imageView"
android:layout_height="wrap_content" android:layout_width="match_parent"
android:text="Hello World!" android:layout_height="match_parent"
android:scaleType="centerCrop"
android:src="@drawable/background_imagemain"
app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="1.0" />
<Button
android:id="@+id/settingsButton"
android:layout_width="56dp"
android:layout_height="56dp"
android:layout_marginTop="16dp"
android:layout_marginEnd="16dp"
android:background="@android:drawable/ic_menu_info_details"
android:backgroundTint="@color/black"
android:contentDescription="Настройки"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent" /> app:layout_constraintTop_toTopOf="parent" />
<androidx.cardview.widget.CardView
android:id="@+id/startTrainingCardView"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="32dp"
android:layout_marginTop="32dp"
android:layout_marginEnd="32dp"
app:cardBackgroundColor="#80000000"
app:cardCornerRadius="8dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/settingsButton">
<Button
android:id="@+id/startTrainingButton"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@android:color/transparent"
android:text="Начать тренировку"
android:textColor="@android:color/white" />
</androidx.cardview.widget.CardView>
<androidx.cardview.widget.CardView
android:id="@+id/templatesCardView"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="32dp"
android:layout_marginTop="16dp"
android:layout_marginEnd="32dp"
app:cardBackgroundColor="#80000000"
app:cardCornerRadius="8dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/startTrainingCardView">
<Button
android:id="@+id/templatesButton"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@android:color/transparent"
android:text="Создать новую тренировку"
android:textColor="@android:color/white" />
</androidx.cardview.widget.CardView>
<androidx.cardview.widget.CardView
android:id="@+id/newTemplateCardView"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="32dp"
android:layout_marginTop="16dp"
android:layout_marginEnd="32dp"
app:cardBackgroundColor="#80000000"
app:cardCornerRadius="8dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/templatesCardView">
<Button
android:id="@+id/newTemplateButton"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@android:color/transparent"
android:text="История тренировок"
android:textColor="@android:color/white" />
</androidx.cardview.widget.CardView>
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/workout"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_marginTop="20dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/newTemplateCardView"
app:layout_constraintVertical_bias="0.0" />
</androidx.constraintlayout.widget.ConstraintLayout> </androidx.constraintlayout.widget.ConstraintLayout>

View File

@ -0,0 +1,106 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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"
android:orientation="vertical"
android:padding="16dp"
android:background="@drawable/background_image2"> <!-- Добавили background -->
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:id="@+id/about_progr_layout"
android:layout_width="match_parent"
android:layout_height="450dp"
android:layout_marginTop="35dp"
android:orientation="vertical"
app:layout_constraintTop_toTopOf="parent"
tools:layout_editor_absoluteX="0dp">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginBottom="16dp"
android:text="О программе"
android:textAlignment="center"
android:textSize="24sp"
android:textStyle="bold" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="8dp"
android:text="Название приложения: Таймер для тренировок"
android:textSize="18sp" />
<TextView
android:id="@+id/textView7"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="8dp"
android:text="Данное приложение поможет пользователю в организации своих тренировок."
android:textSize="18sp" />
<TextView
android:id="@+id/textView9"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="8dp"
android:text="Оно поможет задавать количество подходов и упражнений, устанавливать время работы и отдыха, запускать последние 3 тренировки."
android:textSize="18sp" />
<TextView
android:id="@+id/textView12"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="8dp"
android:text="Можно задавать как интервалы для всех упражнений, так и для каждого отдельно, добавляя названия упражнений."
android:textSize="18sp" />
<TextView
android:id="@+id/versionTextView2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="16dp"
android:text="При возникновении проблем обращаться на почту: stud179277@vyatsu.ru" />
<TextView
android:id="@+id/versionTextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="16dp"
android:text="Версия: 1.0" />
</LinearLayout>
<LinearLayout
android:id="@+id/btn_layout"
android:layout_width="match_parent"
android:layout_height="100dp"
android:layout_marginBottom="16dp"
android:orientation="vertical"
app:layout_constraintBottom_toBottomOf="parent"
tools:layout_editor_absoluteX="0dp">
<Button
android:id="@+id/developersButton"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@drawable/blue_gradient"
android:text="Разработчики" />
<Button
android:id="@+id/btn_on_main"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:background="@drawable/blue_gradient"
android:text="На главную" />
</LinearLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
</LinearLayout>

View File

@ -0,0 +1,137 @@
<?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:id="@+id/main"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@drawable/gradient_pink"
tools:context=".timer">
<TextView
android:id="@+id/textView"
android:layout_width="409dp"
android:layout_height="57dp"
android:layout_marginTop="50dp"
android:gravity="center"
android:text="Тренировка"
android:textAlignment="center"
android:textColor="#040405"
android:textSize="34sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<LinearLayout
android:id="@+id/actions"
android:layout_width="match_parent"
android:layout_height="60dp"
android:layout_marginBottom="100dp"
android:gravity="center"
android:orientation="horizontal"
app:layout_constraintBottom_toBottomOf="parent"
tools:layout_editor_absoluteX="16dp">
<ImageButton
android:id="@+id/play"
android:layout_width="60dp"
android:layout_height="60dp"
android:background="#00FFFFFF"
app:srcCompat="@drawable/icon_play" />
<ImageButton
android:id="@+id/stop"
android:layout_width="60dp"
android:layout_height="60dp"
android:background="#00FFFFFF"
app:srcCompat="@drawable/icon_stop" />
</LinearLayout>
<LinearLayout
android:id="@+id/main_timer"
android:layout_width="match_parent"
android:layout_height="360dp"
android:layout_marginBottom="99dp"
android:gravity="center"
android:orientation="vertical"
app:layout_constraintBottom_toTopOf="@+id/actions"
tools:layout_editor_absoluteX="0dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="54dp"
android:orientation="horizontal">
<TextView
android:id="@+id/textView10"
android:layout_width="548dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:gravity="center"
android:text="Подход № "
android:textAlignment="textEnd"
android:textColor="@color/black"
android:textSize="34sp" />
<TextView
android:id="@+id/number_set"
android:layout_width="400dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:gravity="center"
android:text=" 1"
android:textAlignment="viewStart"
android:textColor="@color/black"
android:textSize="34sp" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="71dp"
android:orientation="horizontal">
<TextView
android:id="@+id/textView11"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_weight="1"
android:text="Упражнение "
android:textAlignment="textEnd"
android:textColor="@color/black"
android:textSize="34sp" />
<TextView
android:id="@+id/num_exercise"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_weight="1"
android:text=" 1"
android:textAlignment="viewStart"
android:textColor="@color/black"
android:textSize="34sp" />
</LinearLayout>
<TextView
android:id="@+id/timerText"
android:layout_width="163dp"
android:layout_height="153dp"
android:layout_gravity="center"
android:gravity="center"
android:text="00:00"
android:textColor="#FFFFFF"
android:textSize="60sp" />
<TextView
android:id="@+id/statusText"
android:layout_width="match_parent"
android:layout_height="70dp"
android:gravity="center"
android:text="Работа"
android:textAlignment="center"
android:textColor="@color/black"
android:textSize="34sp" />
</LinearLayout>
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@ -0,0 +1,39 @@
<?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="wrap_content"
android:layout_marginTop="4dp"
android:layout_marginBottom="4dp">
<LinearLayout
android:id="@+id/layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#410F3FED"
android:orientation="horizontal"
android:paddingTop="8dp"
android:paddingBottom="8dp">
<TextView
android:id="@+id/textView13"
android:layout_width="353dp"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:gravity="center"
android:paddingTop="10dp"
android:paddingBottom="10dp"
android:text="Название упражнения"
android:textColor="#000000"
android:textSize="18sp" />
<ImageButton
android:id="@+id/deleteButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:backgroundTint="#00FFFFFF"
app:srcCompat="@android:drawable/ic_menu_delete" />
</LinearLayout>
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@ -0,0 +1,38 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:layout_marginTop="4dp"
android:layout_marginBottom="4dp">
<LinearLayout
android:id="@+id/layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@drawable/green_rectangle"
android:gravity="center"
android:orientation="horizontal"
android:paddingTop="8dp"
android:paddingBottom="8dp">
<TextView
android:id="@+id/training_text"
android:layout_width="353dp"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:gravity="center"
android:paddingTop="10dp"
android:paddingBottom="10dp"
android:text="Тренировка"
android:textColor="#000000"
android:textSize="18sp" />
<ImageButton
android:id="@+id/deleteButtonTraining"
android:layout_width="48dp"
android:layout_height="48dp"
android:background="@android:drawable/ic_menu_delete" />
</LinearLayout>
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@ -1,6 +1,5 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android"> <adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@drawable/ic_launcher_background" /> <background android:drawable="@color/ic_launcher_background"/>
<foreground android:drawable="@drawable/ic_launcher_foreground" /> <foreground android:drawable="@mipmap/ic_launcher_foreground"/>
<monochrome android:drawable="@drawable/ic_launcher_foreground" />
</adaptive-icon> </adaptive-icon>

View File

@ -1,6 +1,5 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android"> <adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@drawable/ic_launcher_background" /> <background android:drawable="@color/ic_launcher_background"/>
<foreground android:drawable="@drawable/ic_launcher_foreground" /> <foreground android:drawable="@mipmap/ic_launcher_foreground"/>
<monochrome android:drawable="@drawable/ic_launcher_foreground" />
</adaptive-icon> </adaptive-icon>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.8 KiB

After

Width:  |  Height:  |  Size: 4.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 982 B

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.7 KiB

After

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.9 KiB

After

Width:  |  Height:  |  Size: 3.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.8 KiB

After

Width:  |  Height:  |  Size: 6.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.8 KiB

After

Width:  |  Height:  |  Size: 5.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.8 KiB

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.8 KiB

After

Width:  |  Height:  |  Size: 7.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.6 KiB

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -2,4 +2,17 @@
<resources> <resources>
<color name="black">#FF000000</color> <color name="black">#FF000000</color>
<color name="white">#FFFFFFFF</color> <color name="white">#FFFFFFFF</color>
<color name="colorGradientPinkStart">#F54EA2</color>
<color name="colorGradientPinkStop">#FF7676</color>
<color name="colorGradientGreenStart">#42E695</color>
<color name="colorGradientGreenStop">#3BB2B8</color>
<color name="colorGradientBlueStart">#17EAD9</color>
<color name="colorGradientBlueStop">#6078EA</color>
<color name="colorGradientPurpureStart">#7C37D3</color>
<color name="colorGradientPurpureStop">#916AD3</color>
</resources> </resources>

View File

@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="ic_launcher_background">#943DDC</color>
</resources>

View File

@ -1,3 +1,4 @@
<resources> <resources>
<string name="app_name">TimerT</string> <string name="app_name">Timer</string>
<string name="upper_start">START</string>
</resources> </resources>

View File

@ -5,5 +5,6 @@
<!-- <item name="colorPrimary">@color/my_light_primary</item> --> <!-- <item name="colorPrimary">@color/my_light_primary</item> -->
</style> </style>
<style name="Theme.TimerT" parent="Base.Theme.TimerT" />
<style name="Theme.TimerT" parent="Theme.AppCompat.Light.NoActionBar" />
</resources> </resources>

View File

@ -21,3 +21,4 @@ kotlin.code.style=official
# resources declared in the library itself and none from the library's dependencies, # resources declared in the library itself and none from the library's dependencies,
# thereby reducing the size of the R class for that library # thereby reducing the size of the R class for that library
android.nonTransitiveRClass=true android.nonTransitiveRClass=true
kapt.compiler.jvmtarget=11

View File

@ -1,5 +1,5 @@
[versions] [versions]
agp = "8.9.1" agp = "8.10.0"
kotlin = "2.0.21" kotlin = "2.0.21"
coreKtx = "1.16.0" coreKtx = "1.16.0"
junit = "4.13.2" junit = "4.13.2"

View File

@ -10,6 +10,12 @@ pluginManagement {
mavenCentral() mavenCentral()
gradlePluginPortal() gradlePluginPortal()
} }
plugins {
id("com.android.application") version "8.3.2" apply false // Замените на вашу версию
id("org.jetbrains.kotlin.android") version "1.9.0" apply false // Замените на вашу версию Kotlin
id("org.jetbrains.kotlin.kapt") version "1.9.0" apply false // замените на вашу версию Kotlin
id("androidx.room") version "2.7.1" apply false // Добавьте эту строку, заменив на вашу версию Room
}
} }
dependencyResolutionManagement { dependencyResolutionManagement {
repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS) repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
@ -21,4 +27,3 @@ dependencyResolutionManagement {
rootProject.name = "TimerT" rootProject.name = "TimerT"
include(":app") include(":app")