Странная ошибка в навигации между фрагментами

Рейтинг: 0Ответов: 0Опубликовано: 13.01.2023

Все приветствую! Загадочная ошибка, над которой бьюсь уже несколько дней и не могу найти ответа. Логика такая, что при нажатии на item в recyclerView открывается ViewFragment в котором находится ViewPager2 с двумя фрагментами на борту. В первом фрагменте имеется простая форма ввода данных. При нажатии на кнопку сохранить в родительском фрагменте, информация сохраняется в базу данных Room и отправляет пользователя к изначальному фрагменту с recycler view. Проблема заключается в том, что при первом прогоне такого цикла все работает хорошо, но если повторить действия то приложение крашится вот с такой трассировкой:

E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.example.gumbuddy, PID: 30688
    java.lang.IllegalArgumentException: Navigation action/destination com.example.gumbuddy:id/action_exerciseSettingFragment_to_addTrainingFragment cannot be found from the current destination Destination(com.example.gumbuddy:id/addTrainingFragment) label=AddTrainingFragment class=com.example.gumbuddy.ui.fragments.workout.addNewTraining.AddTrainingFragment
        at androidx.navigation.NavController.navigate(NavController.kt:1540)
        at androidx.navigation.NavController.navigate(NavController.kt:1472)
        at androidx.navigation.NavController.navigate(NavController.kt:1930)
        at com.example.gumbuddy.ui.fragments.workout.addNewTraining.ExerciseSettingLinearFragment.saveExerciseSettingLinear(ExerciseSettingLinearFragment.kt:99)
        at com.example.gumbuddy.ui.fragments.workout.addNewTraining.ExerciseSettingLinearFragment.access$saveExerciseSettingLinear(ExerciseSettingLinearFragment.kt:22)
        at com.example.gumbuddy.ui.fragments.workout.addNewTraining.ExerciseSettingLinearFragment$onViewCreated$1.invoke(ExerciseSettingLinearFragment.kt:43)
        at com.example.gumbuddy.ui.fragments.workout.addNewTraining.ExerciseSettingLinearFragment$onViewCreated$1.invoke(ExerciseSettingLinearFragment.kt:41)
        at com.example.gumbuddy.ui.fragments.workout.addNewTraining.ExerciseSettingLinearFragment.onViewCreated$lambda$0(ExerciseSettingLinearFragment.kt:41)
        at com.example.gumbuddy.ui.fragments.workout.addNewTraining.ExerciseSettingLinearFragment.$r8$lambda$73BdcS5f30Wd3-a9i3qoyC7j3Z4(Unknown Source:0)
        at com.example.gumbuddy.ui.fragments.workout.addNewTraining.ExerciseSettingLinearFragment$$ExternalSyntheticLambda0.onChanged(Unknown Source:2)
        at androidx.lifecycle.LiveData.considerNotify(LiveData.java:133)
        at androidx.lifecycle.LiveData.dispatchingValue(LiveData.java:151)
        at androidx.lifecycle.LiveData.setValue(LiveData.java:309)
        at androidx.lifecycle.MutableLiveData.setValue(MutableLiveData.java:50)
        at com.example.gumbuddy.ui.viewmodels.MainViewModel.updateDataFragment(MainViewModel.kt:57)
        at com.example.gumbuddy.ui.fragments.workout.addNewTraining.ExerciseSettingFragment.init$lambda$3$lambda$1(ExerciseSettingFragment.kt:71)
        at com.example.gumbuddy.ui.fragments.workout.addNewTraining.ExerciseSettingFragment.$r8$lambda$iRN9QPNav_1-f_Az-ywsOL_H78w(Unknown Source:0)
        at com.example.gumbuddy.ui.fragments.workout.addNewTraining.ExerciseSettingFragment$$ExternalSyntheticLambda2.onClick(Unknown Source:4)
        at android.view.View.performClick(View.java:7503)
        at android.view.View.performClickInternal(View.java:7480)
        at android.view.View.access$3600(View.java:813)
        at android.view.View$PerformClick.run(View.java:28445)
        at android.os.Handler.handleCallback(Handler.java:938)
        at android.os.Handler.dispatchMessage(Handler.java:99)
        at android.os.Looper.loop(Looper.java:223)
        at android.app.ActivityThread.main(ActivityThread.java:7977)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:603)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:948)
I/Process: Sending signal. PID: 30688 SIG: 9
Disconnected from the target VM, address: 'localhost:40701', transport: 'socket'

Код адаптера RecyclerView изначальный фрагмент:

    val adapter = WorkoutAdapter {
        viewModel.updateCurrentExercise(it)
        val action = AddTrainingFragmentDirections.actionAddTrainingFragmentToExerciseSettingFragment()
        this.findNavController().navigate(action)
    }
    binding.rcViewNewTraining.adapter = adapter
    adapter.submitList(viewModel.addExerciseToTheTrainingList())

Код функции инициализации ViewPager2 во втором фрагменте:

private fun init() = with(binding) {
    val adapter = VpAdapter(activity as FragmentActivity, fList)
    vp2.adapter = adapter
    TabLayoutMediator(tabLayout, vp2) {
        tab, pos -> tab.text = tList[pos]
    }.attach()
    binding.btnSaveTraining.setOnClickListener {
        if (vp2.currentItem == 0) {
            viewModel.updateDataFragment(KEY_LINEAR)
        } else {
            viewModel.updateDataFragment(KEY_PYRAMID)
        }
    }

    binding.btnCleanTraining.setOnClickListener {
        viewModel.updateDataFragment(KEY_CLEAR)
    }
}

Код функции сохранения данных на третьем фрагменте:

private fun saveExerciseSettingLinear(view: View) {
    val idExercise = viewModel.exercise.value?.id
    val approach = binding.edApproach.text
    val repeat = binding.edRepeat.text
    val weight = binding.edWeight.text
    val comment = binding.edComment.text

    if (approach.isEmpty() || repeat.isEmpty() || weight.isEmpty()) {
        Snackbar.make(
            view,
            "Заполните все необходимые поля",
            Snackbar.LENGTH_SHORT
        ).show()
    } else {

        val settingLinear = ExerciseSettingLinear(idExercise, approach.toString().toInt(),
            repeat.toString().toInt(), weight.toString().toDouble(), comment.toString())
        val action = ExerciseSettingFragmentDirections.actionExerciseSettingFragmentToAddTrainingFragment()

        if (comment.isEmpty()) {
            settingLinear.comment = ""
            viewModel.insertExerciseSettingLinear(settingLinear)
            lifecycleScope.launch {
                viewModel.saveIdExerciseSettingLinear()
            }
            findNavController().navigate(action)
        } else {
            viewModel.insertExerciseSettingLinear(settingLinear)
            lifecycleScope.launch {
                viewModel.saveIdExerciseSettingLinear()
            }
            findNavController().navigate(action)
        }
    }
}

Код сохранения данных во viewModel:

//Сохранение настроек упражнения линейного типа в базу данных Room
fun insertExerciseSettingLinear(exerciseSettingLinear: ExerciseSettingLinear) = viewModelScope.launch {
    mainRepository.insertExerciseSettingLinear(exerciseSettingLinear)
}
//Получить все настройки по ID записи
suspend fun getIdExerciseSettingLinear(id: Int): ExerciseSettingLinear = withContext(Dispatchers.IO) {
    mainRepository.getIdExerciseSettingLinear(id)
}
//Получить ID последней записи в базе
private fun updateLastIdSettingLinear() = mainRepository.getLastIdExerciseSettingLinear()

Репозиторий:

class MainRepository @Inject constructor(
    private val trainingDao: TrainingDao,
    private val linearDao: LinearDao,
    private val pyramidDao: PyramidDao
) {
    suspend fun insertTraining(training: Training) = trainingDao.insertTraining(training)
    suspend fun insertExerciseSettingLinear(exerciseSettingLinear: ExerciseSettingLinear) = linearDao.insertExerciseSettingLinear(exerciseSettingLinear)
    suspend fun insertExerciseSettingPyramid(exerciseSettingPyramid: ExerciseSettingPyramid) = pyramidDao.insertExerciseSettingPyramid(exerciseSettingPyramid)

    fun getIdExerciseSettingLinear(id: Int): ExerciseSettingLinear = linearDao.getIdExerciseSettingLinear(id)
    fun getLastIdExerciseSettingLinear(): Int = linearDao.getLastIdExerciseSettingLinear()
}

Dao interface:

@Dao
interface LinearDao {
    @Insert(onConflict = OnConflictStrategy.REPLACE)
    suspend fun insertExerciseSettingLinear(exerciseSettingLinear: ExerciseSettingLinear)

    @Query("SELECT * FROM exercise_setting_linear_table WHERE id = :id")
    fun getIdExerciseSettingLinear(id: Int?): ExerciseSettingLinear

    @Query("SELECT MAX(id) FROM exercise_setting_linear_table")
    fun getLastIdExerciseSettingLinear(): Int
}

Ответы

Ответов пока нет.