Actualmente estoy implementando el Componente de navegación en mi aplicación, pero parece que NavHostFragment simplemente no funciona sin importar lo que haga.
Lo intenté, reconstruí, invalidé y reinicié, cambié los nombres y actualicé mi Android Studio, pero nada parece funcionar. Creo que esta es también la razón por la que recibo un error cuando intento obtener el NavController en mi archivo MainActivity.kt , ya que devuelve un valor nulo.
Android Estudio versión 4.0.1
imagen nav_graph.xml :
nav_graph.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/nav_graph" app:startDestination="@id/mainFragment"> <fragment android:id="@+id/mainFragment" android:name="com.example.movieapp.ui.main.MainFragment" android:label="MainFragment"> <action android:id="@+id/action_mainFragment_to_searchMovieFragment" app:destination="@id/searchMovieFragment" /> </fragment> <fragment android:id="@+id/searchMovieFragment" android:name="com.example.movieapp.ui.search.SearchMovieFragment" android:label="SearchMovieFragment" /> </navigation>actividad_principal.xml
<?xml version="1.0" encoding="utf-8"?> <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" xmlns:app="http://schemas.android.com/apk/res-auto" android:id="@+id/container" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".activity.MainActivity"> <include layout="@layout/appbar" /> <androidx.fragment.app.FragmentContainerView android:id="@+id/nav_host_fragment" android:name="androidx.navigation.fragment.NavHostFragment" android:layout_width="0dp" android:layout_height="0dp" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintRight_toRightOf="parent" app:layout_constraintTop_toTopOf="parent" app:layout_constraintBottom_toBottomOf="parent" app:defaultNavHost="true" app:navGraph="@navigation/nav_graph" /> </androidx.constraintlayout.widget.ConstraintLayout>MainActivity.kt
class MainActivity : AppCompatActivity() { private lateinit var toolbar: Toolbar private val navController by lazy { (supportFragmentManager.findFragmentById(R.id.main_fragment) as NavHostFragment).navController } override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.main_activity) toolbar = findViewById(R.id.mainToolBar) setSupportActionBar(toolbar) setupActionBarWithNavController(navController) } override fun onCreateOptionsMenu(menu: Menu?): Boolean { val inflater: MenuInflater = menuInflater inflater.inflate(R.menu.main_menu_bar, menu) return true } }build.gradle (:aplicación)
apply plugin: 'com.android.application' apply plugin: 'kotlin-android' apply plugin: 'kotlin-android-extensions' apply plugin: 'kotlin-kapt' android { compileSdkVersion 29 buildToolsVersion "29.0.3" defaultConfig { applicationId "com.example.app" minSdkVersion 23 targetSdkVersion 29 versionCode 1 versionName "1.0" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" } buildTypes { debug {} release { minifyEnabled false proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' } dataBinding { enabled true } } } dependencies { implementation fileTree(dir: "libs", include: ["*.jar"]) // Retrofit Libraries implementation 'com.squareup.retrofit2:retrofit:2.6.0' implementation 'com.squareup.retrofit2:converter-gson:2.6.0' // Picasso Library implementation 'com.squareup.picasso:picasso:2.71828' implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version" implementation 'androidx.core:core-ktx:1.3.0' implementation 'androidx.appcompat:appcompat:1.1.0' implementation 'androidx.constraintlayout:constraintlayout:1.1.3' implementation 'androidx.lifecycle:lifecycle-extensions:2.2.0' implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.2.0' implementation 'androidx.legacy:legacy-support-v4:1.0.0' implementation 'androidx.recyclerview:recyclerview:1.1.0' testImplementation 'junit:junit:4.12' androidTestImplementation 'androidx.test.ext:junit:1.1.1' androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0' // Navigation libraries def nav_version = "2.3.0" implementation "androidx.navigation:navigation-fragment-ktx:$nav_version" implementation "androidx.navigation:navigation-ui-ktx:$nav_version" }Inicialmente no tenemos NavHostFragments. Apuntó cada fragmento entre sí, creó acciones de movimiento, pero necesita algo para albergar este movimiento. Ahí es donde entra en juego navigation host fragment . es NavHostFragment ese tipo de intercambios en nuestros fragmentos según sea necesario dentro de un diseño determinado. Entonces, ¿qué diseño debería contener este fragmento de navegación? es el diseño el que se infla durante la actividad principal. Así que abra activity_main.xml .
Debe agregar Containers/NavHostFragment
Cuando elija NavHostFragment para arrastrar, verá los fragmentos de host disponibles.
debemos asegurarnos de escribir esta línea
android:name="androidx.navigation.fragment.NavHostFragment"
<androidx.fragment.app.FragmentContainerView android:id="@+id/navController" android:name="androidx.navigation.fragment.NavHostFragment" android:layout_width="0dp" android:layout_height="0dp" app:defaultNavHost="true" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintRight_toRightOf="parent" app:layout_constraintTop_toTopOf="parent" app:navGraph="@navigation/nav_graph" />Para mí, agregué android:name="androidx.navigation.fragment.NavHostFragment" dentro de FragmentContainerView y trabajé conmigo
La forma en que pude resolver el problema fue yendo a Activity.xml y cambiando la etiqueta de componente/clase de fragmento de androidx.fragment.app.FragmentContainerView a solo fragment . Luego apareció en el panel de hosts del gráfico de navegación.
Como se menciona en Doc , también puede usar el Editor de diseño para agregar un NavHostFragment.
ES POSIBLE QUE NECESITE REINICIAR ANDROID STUDIO DESPUÉS DE ESTO (no mencionado en el documento)
Además, es posible que vea "fragmento" en lugar de "FragmentContainerView" cuando intente agregar un fragmento con el método anterior.
Tuve el mismo problema y lo resolví creando NavHostFragment desde Design , Palette y luego asignando el archivo de recursos de navegación respectivo.
Puede encontrar NavController en actividad como:
class MainActivity : AppCompatActivity() { private lateinit var toolbar: Toolbar private lateinit var navController: NavController override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.main_activity) toolbar = findViewById(R.id.mainToolBar) setSupportActionBar(toolbar) navController = findNavController(R.id.nav_host_fragment) setupActionBarWithNavController(navController) } override fun onCreateOptionsMenu(menu: Menu?): Boolean { val inflater: MenuInflater = menuInflater inflater.inflate(R.menu.main_menu_bar, menu) return true } }private val navController by lazy { (supportFragmentManager.findFragmentById(R.id.main_fragment) as NavHostFragment).navController } Su navController es nulo porque creo que supportFragmentManager.findFragmentById(R.id.main_fragment) devuelve nulo. La identificación de su navHost es R.id.nav_host_fragment según el diseño de su actividad.