From 57f305819a56f9395276e9c25a81c35439e95b75 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=95=D0=BC=D1=86=D0=BE=D0=B2=D0=B0=20=D0=9D=D0=B0=D0=B4?= =?UTF-8?q?=D0=B5=D0=B6=D0=B4=D0=B0?= Date: Thu, 15 May 2025 00:41:41 +0300 Subject: [PATCH] =?UTF-8?q?=D0=B4=D0=BE=D0=B1=D0=B0=D0=B2=D0=BB=D0=B5?= =?UTF-8?q?=D0=BD=D0=B8=D0=B5=20=D0=BE=D1=82=D0=BA=D1=80=D1=8B=D1=82=D0=B8?= =?UTF-8?q?=D1=8F=20=D1=81=D0=BE=D0=B7=D0=B4=D0=B0=D0=BD=D0=BD=D1=8B=D1=85?= =?UTF-8?q?=20=D1=82=D1=80=D0=B5=D0=BD=D0=B8=D1=80=D0=BE=D0=B2=D0=BE=D0=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/example/timert/AddWorkout.kt | 28 ++++++++- .../java/com/example/timert/AllTraining.kt | 1 + .../com/example/timert/CreatingTraining.kt | 61 +++++++++++-------- .../java/com/example/timert/MainActivity.kt | 12 +++- .../timert/data/adapter/TrainingAdapter.kt | 34 +++++++++-- .../example/timert/data/dao/ExerciseDao.kt | 3 + .../example/timert/data/dao/TrainingDao.kt | 3 + .../data/repository/ExerciseRepository.kt | 4 ++ .../data/repository/TrainingRepository.kt | 4 ++ .../data/viewModel/ExerciseViewModel.kt | 20 +++++- .../data/viewModel/TrainingViewModel.kt | 4 ++ 11 files changed, 138 insertions(+), 36 deletions(-) diff --git a/app/src/main/java/com/example/timert/AddWorkout.kt b/app/src/main/java/com/example/timert/AddWorkout.kt index c23779e..b93a5a4 100644 --- a/app/src/main/java/com/example/timert/AddWorkout.kt +++ b/app/src/main/java/com/example/timert/AddWorkout.kt @@ -34,12 +34,13 @@ class AddWorkout : AppCompatActivity() { 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) @@ -48,6 +49,27 @@ class AddWorkout : AppCompatActivity() { 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 { @@ -85,7 +107,7 @@ class AddWorkout : AppCompatActivity() { ) workoutViewModel.insert(newWorkout) - Toast.makeText(this, "Упражнение сохранено", Toast.LENGTH_SHORT).show() + Toast.makeText(this, "Тренировка сохранена", Toast.LENGTH_SHORT).show() isSave = true diff --git a/app/src/main/java/com/example/timert/AllTraining.kt b/app/src/main/java/com/example/timert/AllTraining.kt index b69d582..47c17ba 100644 --- a/app/src/main/java/com/example/timert/AllTraining.kt +++ b/app/src/main/java/com/example/timert/AllTraining.kt @@ -63,6 +63,7 @@ class AllTraining : AppCompatActivity() { trainingId = 0 ) exerciseViewModel.insert(newExercise) + //exerciseViewModel.addUnsavedExercise(newExercise) Toast.makeText(this, "Упражнение сохранено", Toast.LENGTH_SHORT).show() isSave = true finish() diff --git a/app/src/main/java/com/example/timert/CreatingTraining.kt b/app/src/main/java/com/example/timert/CreatingTraining.kt index 512133e..e953674 100644 --- a/app/src/main/java/com/example/timert/CreatingTraining.kt +++ b/app/src/main/java/com/example/timert/CreatingTraining.kt @@ -13,6 +13,7 @@ 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 @@ -20,10 +21,12 @@ 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 @@ -40,46 +43,52 @@ class CreatingTraining : AppCompatActivity() { v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom) insets } - - - - viewModel = ViewModelProvider( - this, - ViewModelProvider.AndroidViewModelFactory.getInstance(application) - )[ExerciseViewModel::class.java] - - name_training = findViewById(R.id.name_training) numSets = findViewById(R.id.numbers_of_sets) restSets = findViewById(R.id.rest_sets) + + val recyclerView = findViewById(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) } - // adapter = ExerciseAdapter(this) - val recyclerView = findViewById(R.id.exercise) + + recyclerView.adapter = adapter recyclerView.layoutManager = LinearLayoutManager(this) - - - viewModel.allExercise.observe(this) { exercises -> - exercises?.let { - adapter.setExercises(it) + 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()) } - val trainingViewModel = ViewModelProvider( - this, - ViewModelProvider.AndroidViewModelFactory.getInstance(application) - )[TrainingViewModel::class.java] - 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 buttonSave: Button = findViewById(R.id.btn_save) buttonSave.setOnClickListener { val name = name_training.text.toString() val numS = numSets.text.toString() diff --git a/app/src/main/java/com/example/timert/MainActivity.kt b/app/src/main/java/com/example/timert/MainActivity.kt index 8c4dc3c..b2bfb2c 100644 --- a/app/src/main/java/com/example/timert/MainActivity.kt +++ b/app/src/main/java/com/example/timert/MainActivity.kt @@ -34,7 +34,17 @@ class MainActivity : AppCompatActivity() { } adapter = TrainingAdapter( onDeleteWorkout = { id -> workoutViewModel.deleteWorkoutById(id) }, - onDeleteTraining = { id -> trainingViewModel.deleteTrainingById(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(R.id.workout) diff --git a/app/src/main/java/com/example/timert/data/adapter/TrainingAdapter.kt b/app/src/main/java/com/example/timert/data/adapter/TrainingAdapter.kt index 836f1a2..79fe8be 100644 --- a/app/src/main/java/com/example/timert/data/adapter/TrainingAdapter.kt +++ b/app/src/main/java/com/example/timert/data/adapter/TrainingAdapter.kt @@ -1,5 +1,6 @@ package com.example.timert.data.adapter +import android.content.Intent import android.view.LayoutInflater import android.view.View import android.view.ViewGroup @@ -9,14 +10,20 @@ 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 onDeleteTraining: (Int) -> Unit, + private val onWorkoutClick: (Workout) -> Unit, + private val onTrainingClick: (Training) -> Unit + ) : ListAdapter(DiffCallback()) { companion object { @@ -35,8 +42,8 @@ class TrainingAdapter( private val onDeleteWorkout: (Int) -> Unit, 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) - TYPE_TRAINING_WITH_EXERCISES -> TrainingViewHolder(view, onDeleteTraining) + TYPE_WORKOUT -> WorkoutViewHolder(view, onDeleteWorkout, onWorkoutClick) + TYPE_TRAINING_WITH_EXERCISES -> TrainingViewHolder(view, onDeleteTraining, onTrainingClick) else -> throw IllegalArgumentException("Invalid view type") } } @@ -48,23 +55,40 @@ class TrainingAdapter( private val onDeleteWorkout: (Int) -> Unit, } } - class WorkoutViewHolder(itemView: View, private val onDelete: (Int) -> Unit) : + class WorkoutViewHolder(itemView: View, private val onDelete: (Int) -> Unit, + private val onClick: (Workout) -> Unit) : RecyclerView.ViewHolder(itemView) { fun bind(workout: Workout) { itemView.findViewById(R.id.training_text).text = workout.name itemView.findViewById(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) : + 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(R.id.training_text).text = trainingWithExercise.training.name itemView.findViewById(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) + } } } diff --git a/app/src/main/java/com/example/timert/data/dao/ExerciseDao.kt b/app/src/main/java/com/example/timert/data/dao/ExerciseDao.kt index 92dc283..547f23c 100644 --- a/app/src/main/java/com/example/timert/data/dao/ExerciseDao.kt +++ b/app/src/main/java/com/example/timert/data/dao/ExerciseDao.kt @@ -26,4 +26,7 @@ interface ExerciseDao { @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> } \ No newline at end of file diff --git a/app/src/main/java/com/example/timert/data/dao/TrainingDao.kt b/app/src/main/java/com/example/timert/data/dao/TrainingDao.kt index 34d1cce..22fcf1b 100644 --- a/app/src/main/java/com/example/timert/data/dao/TrainingDao.kt +++ b/app/src/main/java/com/example/timert/data/dao/TrainingDao.kt @@ -38,4 +38,7 @@ interface TrainingDao { @Transaction @Query("SELECT * FROM training") fun getTrainingsWithExercises(): LiveData> + + @Query("SELECT * FROM training WHERE id = :id") + fun getTrainingById(id: Int): LiveData } diff --git a/app/src/main/java/com/example/timert/data/repository/ExerciseRepository.kt b/app/src/main/java/com/example/timert/data/repository/ExerciseRepository.kt index 44e1640..4bf82f1 100644 --- a/app/src/main/java/com/example/timert/data/repository/ExerciseRepository.kt +++ b/app/src/main/java/com/example/timert/data/repository/ExerciseRepository.kt @@ -14,4 +14,8 @@ class ExerciseRepository(private val exerciseDao:ExerciseDao){ exerciseDao.deleteById(id) } + fun getExercisesByTrainingId(trainingId: Int): LiveData> { + return exerciseDao.getExercisesByTrainingId(trainingId) + } + } \ No newline at end of file diff --git a/app/src/main/java/com/example/timert/data/repository/TrainingRepository.kt b/app/src/main/java/com/example/timert/data/repository/TrainingRepository.kt index 70c3b02..e9c5116 100644 --- a/app/src/main/java/com/example/timert/data/repository/TrainingRepository.kt +++ b/app/src/main/java/com/example/timert/data/repository/TrainingRepository.kt @@ -20,4 +20,8 @@ class TrainingRepository(private val trainingDao: TrainingDao) { trainingDao.deleteById(id) } + fun getTrainingById(id: Int): LiveData { + return trainingDao.getTrainingById(id) + } + } \ No newline at end of file diff --git a/app/src/main/java/com/example/timert/data/viewModel/ExerciseViewModel.kt b/app/src/main/java/com/example/timert/data/viewModel/ExerciseViewModel.kt index d3184b7..0c955a8 100644 --- a/app/src/main/java/com/example/timert/data/viewModel/ExerciseViewModel.kt +++ b/app/src/main/java/com/example/timert/data/viewModel/ExerciseViewModel.kt @@ -3,6 +3,7 @@ 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 @@ -12,7 +13,8 @@ import kotlinx.coroutines.launch class ExerciseViewModel(application: Application):AndroidViewModel(application){ private val repository: ExerciseRepository val allExercise: LiveData> - + private val _unsavedExercises = MutableLiveData>(emptyList()) + val unsavedExercises: LiveData> = _unsavedExercises init{ val exercisesDao = AppDatabase.getDatabase(application).exerciseDao() repository = ExerciseRepository(exercisesDao) @@ -25,4 +27,20 @@ class ExerciseViewModel(application: Application):AndroidViewModel(application){ fun deleteExerciseById(id: Int) = viewModelScope.launch { repository.deleteExerciseById(id) } + + fun getExercisesByTrainingId(trainingId: Int): LiveData> { + 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() + } } \ No newline at end of file diff --git a/app/src/main/java/com/example/timert/data/viewModel/TrainingViewModel.kt b/app/src/main/java/com/example/timert/data/viewModel/TrainingViewModel.kt index 18dec9e..ccb1aa1 100644 --- a/app/src/main/java/com/example/timert/data/viewModel/TrainingViewModel.kt +++ b/app/src/main/java/com/example/timert/data/viewModel/TrainingViewModel.kt @@ -38,6 +38,10 @@ class TrainingViewModel (application: Application): AndroidViewModel(application repository.delete(training) } + fun getTrainingById(id: Int): LiveData { + return repository.getTrainingById(id) + } + fun insertTrainingAndLinkExercises(training: Training) { viewModelScope.launch { val newId = repository.insert(training) // возвращает id