# #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, которая содержит фрагменты навигации