Ошибка навигации Android: java.lang.IllegalArgumentException: назначение навигации com.example --- неизвестно этому NavController - PullRequest
0 голосов
/ 19 октября 2019

Я получаю сообщение об ошибке: java.lang.IllegalArgumentException, ошибка возникает только тогда, когда я перехожу к RegisterFragment из LoginFragment и затем нажимаю кнопку «Назад», чтобы перейти к предыдущему фрагменту (LoginFragment) и ввести адрес электронной почты и пароль. и нажмите кнопку входа. Когда я комментирую строку view!!.findNavController().navigate(LoginFragmentDirections.actionLoginFragmentToHomeContainerFragment()), ошибка не возникает, но я должен перейти к HomeFragment. Как это исправить?

Примечание: Ошибка не возникает, если вы не переходите к RegisterFragment

LoginFragment:

override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View?
{
    val binding: FragmentLoginBinding = DataBindingUtil.inflate(inflater, R.layout.fragment_login, container, false)

    val login = binding.loginBtn
    val emailField = binding.inputEmail
    val passwordField = binding.inputPassword
    val signUp = binding.loginSignup

    binding.viewModel = viewModel
    binding.lifecycleOwner = this

    signUp.setOnClickListener {
        view!!.findNavController().navigate(LoginFragmentDirections.actionLoginFragmentToRegisterFragment())
    }

    login.setOnClickListener {
        val email = emailField.text.toString().trim()
        val password = passwordField.text.toString().trim()

        if(email.isEmpty())
        {
            .................
        }

        if(!Patterns.EMAIL_ADDRESS.matcher(email).matches())
        {
            .................
        }

        viewModel.userLogin(email,password)
    }

    viewModel.loginAuthData.observe(this, Observer { userAuthData ->
        if(userAuthData.checkAuth != null)
        {
            if(userAuthData.checkAuth!!)
            {
                Snackbar.make(activity!!.findViewById(android.R.id.content), "Auth Pass", Snackbar.LENGTH_SHORT).show()
                //The error doesn't occur if i comment this line >>
                view!!.findNavController().navigate(LoginFragmentDirections.actionLoginFragmentToHomeContainerFragment())
            }
            else
            {
                Snackbar.make(activity!!.findViewById(android.R.id.content), "Auth Fail", Snackbar.LENGTH_SHORT).show()
            }
        }
    })

    return binding.root
}

Ошибка:

  Process: com.example.---, PID: 24721
  java.lang.IllegalArgumentException: navigation destination com.example.---:id/action_loginFragment_to_homeContainerFragment is unknown to this NavController
    at androidx.navigation.NavController.navigate(NavController.java:789)
    at androidx.navigation.NavController.navigate(NavController.java:730)
    at androidx.navigation.NavController.navigate(NavController.java:716)
    at androidx.navigation.NavController.navigate(NavController.java:907)
    at com.example.---.ui.login.LoginFragment$onCreateView$3.onChanged(LoginFragment.kt:71)
    at com.example.---.ui.login.LoginFragment$onCreateView$3.onChanged(LoginFragment.kt:20)
    at androidx.lifecycle.LiveData.considerNotify(LiveData.java:131)
    at androidx.lifecycle.LiveData.dispatchingValue(LiveData.java:149)
    at androidx.lifecycle.LiveData.setValue(LiveData.java:307)
    at androidx.lifecycle.MutableLiveData.setValue(MutableLiveData.java:50)
    at com.example.---.viewModel.LoginViewModel.authCallBack(LoginViewModel.kt:37)
    at com.example.---.viewModel.LoginViewModel.access$authCallBack(LoginViewModel.kt:12)
    at com.example.---.viewModel.LoginViewModel$firebaseUserAuth$1.invoke(LoginViewModel.kt:15)
    at com.example.---.viewModel.LoginViewModel$firebaseUserAuth$1.invoke(LoginViewModel.kt:12)
    at com.example.---.data.FirebaseUserAuth$login$1.onComplete(FirebaseUserAuth.kt:27)
    at com.google.android.gms.tasks.zzj.run(Unknown Source)
    at android.os.Handler.handleCallback(Handler.java:751)
    at android.os.Handler.dispatchMessage(Handler.java:95)
    at android.os.Looper.loop(Looper.java:154)
    at android.app.ActivityThread.main(ActivityThread.java:6077)
    at java.lang.reflect.Method.invoke(Native Method)
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:866)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:756)

Ответы [ 2 ]

0 голосов
/ 20 октября 2019

Вы используете viewModel.loginAuthData.observe(this, Observer {}) в onCreateView(), т. Е. Используете Fragment (через this) в качестве LifecycleOwner для своих наблюдений. Это всегда неправильно - вы должны вместо этого использовать viewLifecycleOwner при наблюдении с onCreateView():

viewModel.loginAuthData.observe(viewLifecycleOwner, Observer {
   ...
})

Как работает LiveData, он продолжает оставаться зарегистрированным до тех пор, пока данный LifecycleOwner не будет уничтожен. Когда вы передаете this, он ожидает уничтожения самого фрагмента. Однако фрагменты не уничтожаются в заднем стеке (уничтожается только их представление и, следовательно, viewLifecycleOwner). Это означает, что оригинал LiveData никогда не отменяет регистрацию своего Обозревателя.

Это означает, что когда onCreateView() происходит во второй раз (т. Е. Вы нажимаете кнопку «Назад» и представление воссоздается), секунда Наблюдатель создан и зарегистрирован. Теперь у вас есть два Наблюдателя, работающих одновременно. Когда они оба бегут, первый успешно запускается и вызывает navigate(). Когда запускается второй, NavController уже переместился в следующий пункт назначения, поэтому любые действия, зарегистрированные в предыдущем пункте назначения, больше не найдены, что дает вам IllegalArgumentException.

При использовании viewLifecycleOwner, оригиналLiveData корректно уничтожается при разрушении представления фрагмента. Это означает, что при ответном ударе и повторном вызове onCreateView одновременно активен только один наблюдатель, и вы не столкнетесь с этой проблемой.

0 голосов
/ 19 октября 2019

Попробуйте получить NavController, содержащий Activity Activity.findNavController(IdOfView) вместо view!!.findNavController()

Подробнее о навигации: https://developer.android.com/reference/kotlin/androidx/navigation/package-summary#findnavcontroller

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...