java.lang.Исключение IllegalStateException: в приложении Kotlin NavigationComponent нет текущего узла навигации

# #firebase #kotlin #navigation-drawer

Вопрос:

Я разрабатывал приложение Kotin, которое использует навигационный компонент для перемещения между различными экранами приложения.

Мои проблемы возникают, когда я пытаюсь отделить root_navigation.xml из числа main_navigation.xml

Основная структура моего приложения-это заставка, которая отправляет вас на экран входа в систему, где вы можете проверить, какая база данных работает с помощью поставщика Googe или поставщика электронной почты/пароля.

Аутентификация HGoogle работает нормально и отправляет вас на домашнюю страницу приложения, но аутентификация с помощью электронной почты/пароля приводит к ошибке заголовка выше.

Код моих навигационных файлов выглядит следующим образом

mobile_navigation.xml

 <?xml version="1.0" encoding="utf-8"?>
<navigation 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/mobile_navigation"
    app:startDestination="@ id/nav_login">

    <fragment
        android:id="@ id/nav_login"
        android:name="com.example.appadoskotlin2.ui.login.LoginFragment"
        android:label="Login"
        tools:layout="@layout/fragment_login">
        <action
            android:id="@ id/navigation_login_to_navigation_home"
            app:destination="@id/nav_home"/>
    </fragment>
    <fragment
        android:id="@ id/nav_home"
        android:name="com.example.appadoskotlin2.ui.home.HomeFragment"
        android:label="@string/menu_home"
        tools:layout="@layout/fragment_home">
        <action
            android:id="@ id/navigation_home_to_navigation_item_home"
            app:destination="@id/navigation_item_home"/>
    </fragment>
    <fragment
        android:id="@ id/navigation_item_home"
        android:name="com.example.appadoskotlin2.ui.home.ItemServiceFragment"
        android:label="Servicios"
        tools:layout="@layout/item_list">
        <argument
            android:name="item"
            app:argType="com.example.appadoskotlin2.data.Service"/>

    </fragment>
    <fragment
        android:id="@ id/nav_contract"
        android:name="com.example.appadoskotlin2.ui.contract.ContractFragment"
        android:label="@string/menu_contract"
        tools:layout="@layout/fragment_contract">
    <action
        android:id="@ id/navigation_contract_to_navigation_item_contract"
        app:destination="@id/navigation_item_contract"/>
    </fragment>

    <fragment
        android:id="@ id/navigation_item_contract"
        android:name="com.example.appadoskotlin2.ui.home.ItemServiceFragment"
        android:label="Servicios"
        tools:layout="@layout/item_list">
    </fragment>

    <fragment
        android:id="@ id/nav_publish"
        android:name="com.example.appadoskotlin2.ui.publish.PublishFragment"
        android:label="@string/menu_publish"
        tools:layout="@layout/fragment_publish">
        <action
            android:id="@ id/navigation_publish_to_navigation_item_publish"
            app:destination="@id/navigation_item_publish"/>
    </fragment>
        <fragment
            android:id="@ id/navigation_item_publish"
            android:name="com.example.appadoskotlin2.ui.publish.ItemPublishFragment"
            android:label="Servicios"
            tools:layout="@layout/item_list">
        </fragment>

</navigation>
 

root_navigation.xml

 <?xml version="1.0" encoding="utf-8"?>
<navigation 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/root_navigation"
    app:startDestination="@ id/navigation_splash">

    <activity
        android:id="@ id/navigation_splash"
        android:name="com.example.appadoskotlin2.SplashActivity"
        android:label="activity_splash"
        tools:layout="@layout/activity_splash" >
        <action
            android:id="@ id/action_navigation_splash_to_navigation_login"
            app:destination="@id/navigation_login" />
    </activity>
    <activity
        android:id="@ id/navigation_login"
        android:name="com.example.appadoskotlin2.MainActivity"
        android:label="activity_login"
        tools:layout="@layout/activity_main" >
        <action
            android:id="@ id/action_navigation_login_to_navigation_main"
            app:destination="@id/navigation_main" />
    </activity>
    <activity
        android:id="@ id/navigation_main"
        android:name="com.example.appadoskotlin2.MainActivity"
        android:label="MainActivity"
        tools:layout="@layout/activity_main"/>

</navigation>
 

And the code of my LoginFragment and MainActivty of the App are these:

MainActivity.kt

 package com.example.appadoskotlin2

import android.os.Bundle
import android.view.Menu
import com.google.android.material.snackbar.Snackbar
import com.google.android.material.navigation.NavigationView
import androidx.navigation.findNavController
import androidx.navigation.ui.AppBarConfiguration
import androidx.navigation.ui.navigateUp
import androidx.navigation.ui.setupActionBarWithNavController
import androidx.navigation.ui.setupWithNavController
import androidx.drawerlayout.widget.DrawerLayout
import androidx.appcompat.app.AppCompatActivity
import com.example.appadoskotlin2.databinding.ActivityMainBinding
import com.example.appadoskotlin2.ui.home.HomeFragment

class MainActivity : AppCompatActivity() {

    private lateinit var appBarConfiguration: AppBarConfiguration
    private lateinit var binding: ActivityMainBinding


    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        binding = ActivityMainBinding.inflate(layoutInflater)
        setContentView(binding.root)

        setSupportActionBar(binding.appBarMain.toolbar)

        binding.appBarMain.fab.setOnClickListener { view ->
            Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
                .setAction("Action", null).show()
        }

        val drawerLayout: DrawerLayout = binding.drawerLayout
        val navView: NavigationView = binding.navView
        val navController = findNavController(R.id.nav_host_fragment_content_main)
        // Passing each menu ID as a set of Ids because each
        // menu should be considered as top level destinations.
        appBarConfiguration = AppBarConfiguration(setOf(R.id.nav_login,
            R.id.nav_home, R.id.nav_contract, R.id.nav_publish), drawerLayout)
        setupActionBarWithNavController(navController, appBarConfiguration)
        navView.setupWithNavController(navController)
    }

    override fun onCreateOptionsMenu(menu: Menu): Boolean {
        // Inflate the menu; this adds items to the action bar if it is present.
        menuInflater.inflate(R.menu.main, menu)
        return true
    }

    override fun onSupportNavigateUp(): Boolean {
        val navController = findNavController(R.id.nav_host_fragment_content_main)
        return navController.navigateUp(appBarConfiguration) || super.onSupportNavigateUp()
    }
}
 

Логин-фрагмент.кт

 package com.example.appadoskotlin2.ui.login

import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.Toast
import androidx.fragment.app.Fragment
import androidx.navigation.NavController
import androidx.navigation.Navigation
import com.example.appadoskotlin2.R
import com.example.appadoskotlin2.databinding.FragmentLoginBinding
import com.example.appadoskotlin2.ui.diologs.LoginDialog
import com.example.appadoskotlin2.ui.diologs.RegisterDialog
import com.google.android.gms.auth.api.signin.GoogleSignIn
import com.google.android.gms.auth.api.signin.GoogleSignInClient
import com.google.android.gms.auth.api.signin.GoogleSignInOptions
import com.google.android.material.button.MaterialButton
import com.google.firebase.FirebaseApp
import com.google.firebase.auth.FirebaseAuth

class LoginFragment: Fragment() {
    private val RC_SIGN_IN = 123

    private lateinit var navController : NavController
    private var _binding: FragmentLoginBinding? = null
    private val binding get() = _binding!!
    private var firebaseAuth: FirebaseAuth? = null
    private var mGoogleSignIn: GoogleSignInClient? = null
    private var btn_google: MaterialButton? = null
    private var btn_register: MaterialButton? = null
    private var btn_login: MaterialButton? = null
    private var diolog_register: RegisterDialog? = null
    private var diolog_login: LoginDialog? = null

    //TODO("Configurar firebase y linkear la vista")

    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?,
    ): View? {
        _binding = FragmentLoginBinding.inflate(inflater, container, false)
        val root: View = binding.root

        initView(root)

        initListeners()

        return root
    }

    private fun initListeners() {
        val loginActivity: LoginFragment = this
        btn_google?.setOnClickListener(View.OnClickListener {
            createRequest()
            signIn()
        })
        btn_register?.setOnClickListener(View.OnClickListener {
            diolog_register = RegisterDialog(firebaseAuth, loginActivity)
            fragmentManager?.let { it1 -> diolog_register!!.show(it1, "RegisterDiolog") }
        })
        btn_login?.setOnClickListener(View.OnClickListener {
            diolog_login = LoginDialog(firebaseAuth, this.context)
            fragmentManager?.let { it1 -> diolog_login!!.show(it1, "LoginDiolog") }
        })

    }

    fun initView(root: View){
        btn_google = root.findViewById(R.id.btn_google)
        btn_register = root.findViewById(R.id.btn_register)
        btn_login = root.findViewById(R.id.btn_login)
        context?.let { FirebaseApp.initializeApp(it) }
        firebaseAuth = FirebaseAuth.getInstance()
    }
    private fun signIn() {
        val signInIntent = mGoogleSignIn!!.signInIntent
        startActivityForResult(signInIntent, RC_SIGN_IN)
        showHome()
    }

    private fun showHome() {
        navController = Navigation.findNavController(this.requireView())
        navController.navigate(R.id.navigation_login_to_navigation_home)
        Toast.makeText(context, "Login completed successfully", Toast.LENGTH_SHORT).show()
    }

    private fun createRequest() {
        val gso = GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
            .requestIdToken("786240463795-o92gljk39cmdd0pra162arebskntkdu5.apps.googleusercontent.com")
            .requestEmail()
            .build()
        mGoogleSignIn = GoogleSignIn.getClient(this.activity, gso)
    }
    override fun onDestroyView() {
        super.onDestroyView()
        _binding = null
    }
}
 

Как я уже сказал, все работает нормально, пока я не попытаюсь разделить навигацию в этих двух файлах, чтобы различать навигацию при входе в систему и навигацию внутри приложения после входа пользователя в систему.

Я не знаю, связан ли факт того, что экран входа является фрагментом, с чем связана проблема.

Я надеюсь, что вы сможете помочь, и если это так, заранее примите благодарность !

[ПРАВИТЬ]

Добавил navigation.xml как я изменил его после нескольких советов:

Все из-за той же ошибки.

mobile_navigation.xml

введите описание изображения здесь

root_navigation.xml

введите описание изображения здесь

Комментарии:

1. Вы добавили зависимости компонентов навигации ?? В сборке приложения.gradle

2. Конечно, добавляется зависимость

Ответ №1:

Убедитесь, что вы правильно реализовали навигационный график. используйте фрагменты.

 root_navigation.xml
 

введите описание изображения здесь

 mobile_navigation.xml
 

введите описание изображения здесь

добавьте сюда нужные фрагменты, по которым вы хотите перейти при входе в систему.

(Я предлагаю использовать фрагмент входа в систему на экране заставки для запуска вашего приложения. и другие фрагменты реализуются через основную деятельность)

Комментарии:

1. Я внедряю изменения, и все равно из-за той же ошибки.

2. Можете ли вы добавить снимок экрана с навигационным графиком, о котором идет речь?

3. Я только что добавил !

4. Хорошо, я обновлю свой ответ.

5. Оке, я понимаю вашу точку зрения, но в моем случае мой Логин-это действие, как и мой экран. Так что структура совсем иная, не так ли? Как я вижу в root_navigation.xml следует реализовать навигацию действий к области navigation_main, которая содержит фрагменты навигации