Reputation: 283
I just got my code to compile and when I try to start the app I receive the error. I'm currently trying to setup RecycleView for my class project. My goal is to make the RecycleView show content sorta like the reddit mobile app. I thought my RecycleView named "scrollview1" had a navcontroller setup. Not sure why I'm getting this output
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.john.chanapi/com.john.chanapi.MainActivity}: java.lang.IllegalStateException: Activity com.john.chanapi.MainActivity@1850938 does not have a NavController set on 2131230866
My MainActivity.kt:
package com.john.chanapi
import android.os.Bundle
import com.google.android.material.floatingactionbutton.FloatingActionButton
import com.google.android.material.snackbar.Snackbar
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 com.google.android.material.navigation.NavigationView
import androidx.appcompat.app.AppCompatActivity
import androidx.appcompat.widget.Toolbar
import android.view.Menu
import android.view.View
class MainActivity : AppCompatActivity() {
private lateinit var appBarConfiguration: AppBarConfiguration
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val toolbar: Toolbar = findViewById(R.id.toolbar)
setSupportActionBar(toolbar)
val fab: FloatingActionButton = findViewById(R.id.fab)
fab.setOnClickListener { view ->
Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
.setAction("Action", null).show()
}
val drawerLayout: DrawerLayout = findViewById(R.id.drawer_layout)
val navView: NavigationView = findViewById(R.id.nav_view)
val navController = findNavController(R.id.scrollview1)
// 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_home, R.id.nav_new, R.id.nav_rising,
R.id.nav_top, R.id.nav_inbox, R.id.nav_message
), 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.scrollview1)
return navController.navigateUp(appBarConfiguration) || super.onSupportNavigateUp()
}
}
My activity_main.xml:
<?xml version="1.0" encoding="utf-8"?>
<androidx.drawerlayout.widget.DrawerLayout 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/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
tools:openDrawer="start">
<include
layout="@layout/app_bar_main"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<com.google.android.material.navigation.NavigationView
android:id="@+id/nav_view"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="start"
android:fitsSystemWindows="true"
app:headerLayout="@layout/nav_header_main"
app:menu="@menu/activity_main_drawer" />
</androidx.drawerlayout.widget.DrawerLayout>
Upvotes: 28
Views: 20945
Reputation: 1394
use simple <fragment>
tag instead of
<com.google.android.material.navigation.NavigationView>
Upvotes: 7
Reputation: 1856
To be on the safer side, (within an Activity) avoid using findNavController(Int)
to initialize a NavController
instead initialize it from NavHostFragment
as shown
val navHostFragment =
supportFragmentManager.findFragmentById(R.id.navigation_host) as NavHostFragment
val navController: NavController = navHostFragment.navController
Upvotes: 60
Reputation: 1380
Inside onCreate views are not inflated yet. When you call findNavController it will fail.
One solution is to override the onViewCreated method and move the code after setSupportActionBar into onViewCreated.
Sample
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val toolbar: Toolbar = findViewById(R.id.toolbar)
setSupportActionBar(toolbar)
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
val fab: FloatingActionButton = findViewById(R.id.fab)
fab.setOnClickListener {}
val drawerLayout: DrawerLayout = findViewById(R.id.drawer_layout)
val navView: NavigationView = findViewById(R.id.nav_view)
val navController = findNavController(R.id.scrollview1)
// 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_home, R.id.nav_new, R.id.nav_rising,
R.id.nav_top, R.id.nav_inbox, R.id.nav_message
), drawerLayout
)
setupActionBarWithNavController(navController, appBarConfiguration)
navView.setupWithNavController(navController)
}
Upvotes: 0
Reputation: 2019
val navController = findNavController(R.id.scrollview1)
because R.id.scrollview1
will find the UI component that is RecyclerView
,
not NavController
Upvotes: 0