无法从 android 中的片段访问 NavHostFragment
NavHostFragment not accessible from fragment in android
我尝试从主页片段访问 NavController
但没有成功。花了一整天,但仍然没有成功。该应用程序在 HomeFragment
这行代码中崩溃:
navController = requireActivity().findNavController(R.id.nav_host_fragment)
这是我实现的代码:
HomeFragmnet
class HomeFragment : Fragment() {
private lateinit var homeViewModel: HomeViewModel
private lateinit var recyclerView: RecyclerView
private lateinit var navController: NavController
private var itemList: MutableList<Home?> = ArrayList()
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
navController = requireActivity().findNavController(R.id.nav_host_fragment)
homeViewModel = ViewModelProvider(this).get(HomeViewModel::class.java)
val root = inflater.inflate(R.layout.fragment_home, container, false)
recyclerView = root.findViewById(R.id.homeRecyclerView)
return root
}
}
这是 xml nav_bar.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/nav_home">
<fragment
android:id="@+id/nav_home"
android:name="fi.gambitlabs.pworker.ui.home.HomeFragment"
android:label="@string/menu_home"
tools:layout="@layout/fragment_home" />
</navigation>
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>
content_main.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 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:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior"
tools:showIn="@layout/app_bar_main">
<fragment
android:id="@+id/nav_host_fragment"
android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:defaultNavHost="true"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:navGraph="@navigation/nav_graph" />
</androidx.constraintlayout.widget.ConstraintLayout>
MainActivity
class MainActivity : AppCompatActivity() {
private lateinit var appBarConfiguration: AppBarConfiguration
private lateinit var navController: NavController
private lateinit var navView: NavigationView
override fun onCreate(savedInstanceState: Bundle?) {
// Disable dark mode
AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_NO)
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val toolbar: Toolbar = findViewById(R.id.toolbar)
setSupportActionBar(toolbar)
val drawerLayout: DrawerLayout = findViewById(R.id.drawer_layout)
navView = findViewById(R.id.nav_view)
navController = findNavController(R.id.nav_host_fragment)
// 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), 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)
return navController.navigateUp(appBarConfiguration) || super.onSupportNavigateUp()
}
}
错误日志
E/AndroidRuntime: FATAL EXCEPTION: main
Process: fi.gambitlabs.pworker, PID: 12300
java.lang.RuntimeException: Unable to start activity ComponentInfo{fi.gambitlabs.pworker/fi.gambitlabs.pworker.MainActivity}: android.view.InflateException: Binary XML file line #14 in fi.gambitlabs.pworker:layout/activity_main: Binary XML file line #19 in fi.gambitlabs.pworker:layout/content_main: Error inflating class fragment
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3449)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3601)
at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:85)
at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2066)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loop(Looper.java:223)
at android.app.ActivityThread.main(ActivityThread.java:7656)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:592)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:947)
Caused by: android.view.InflateException: Binary XML file line #14 in fi.gambitlabs.pworker:layout/activity_main: Binary XML file line #19 in fi.gambitlabs.pworker:layout/content_main: Error inflating class fragment
Caused by: android.view.InflateException: Binary XML file line #19 in fi.gambitlabs.pworker:layout/content_main: Error inflating class fragment
Caused by: java.lang.IllegalArgumentException: ID does not reference a View inside this Activity
at android.app.Activity.requireViewById(Activity.java:3375)
at androidx.core.app.ActivityCompat.requireViewById(ActivityCompat.java:366)
at androidx.navigation.Navigation.findNavController(Navigation.java:58)
at *emphasized text*androidx.navigation.ActivityKt.findNavController(Activity.kt:30)
at fi.gambitlabs.pworker.ui.home.HomeFragment.onCreateView(HomeFragment.kt:30)
at androidx.fragment.app.Fragment.performCreateView(Fragment.java:2963)
at androidx.fragment.app.FragmentStateManager.createView(FragmentStateManager.java:518)
at androidx.fragment.app.FragmentStateManager.moveToExpectedState(FragmentStateManager.java:282)
at androidx.fragment.app.FragmentStore.moveToExpectedState(FragmentStore.java:112)
at androidx.fragment.app.FragmentManager.moveToState(FragmentManager.java:1647)
at androidx.fragment.app.FragmentManager.dispatchStateChange(FragmentManager.java:3128)
at androidx.fragment.app.FragmentManager.dispatchViewCreated(FragmentManager.java:3065)
at androidx.fragment.app.Fragment.performViewCreated(Fragment.java:2988)
at androidx.fragment.app.FragmentStateManager.ensureInflatedView(FragmentStateManager.java:392)
at androidx.fragment.app.FragmentStateManager.moveToExpectedState(FragmentStateManager.java:281)
at androidx.fragment.app.FragmentLayoutInflaterFactory.onCreateView(FragmentLayoutInflaterFactory.java:140)
at androidx.fragment.app.FragmentController.onCreateView(FragmentController.java:135)
at androidx.fragment.app.FragmentActivity.dispatchFragmentsOnCreateView(FragmentActivity.java:319)
at androidx.fragment.app.FragmentActivity.onCreateView(FragmentActivity.java:298)
at android.view.LayoutInflater.tryCreateView(LayoutInflater.java:1067)
at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:995)
at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:959)
at android.view.LayoutInflater.rInflate(LayoutInflater.java:1121)
at android.view.LayoutInflater.rInflateChildren(LayoutInflater.java:1082)
at android.view.LayoutInflater.parseInclude(LayoutInflater.java:1261)
at android.view.LayoutInflater.rInflate(LayoutInflater.java:1117)
at android.view.LayoutInflater.rInflateChildren(LayoutInflater.java:1082)
E/AndroidRuntime: at android.view.LayoutInflater.parseInclude(LayoutInflater.java:1261)
at android.view.LayoutInflater.rInflate(LayoutInflater.java:1117)
at android.view.LayoutInflater.rInflateChildren(LayoutInflater.java:1082)
at android.view.LayoutInflater.inflate(LayoutInflater.java:680)
at android.view.LayoutInflater.inflate(LayoutInflater.java:532)
at android.view.LayoutInflater.inflate(LayoutInflater.java:479)
at androidx.appcompat.app.AppCompatDelegateImpl.setContentView(AppCompatDelegateImpl.java:699)
at androidx.appcompat.app.AppCompatActivity.setContentView(AppCompatActivity.java:195)
at fi.gambitlabs.Pworker.MainActivity.onCreate(MainActivity.kt:28)
at android.app.Activity.performCreate(Activity.java:8000)
at android.app.Activity.performCreate(Activity.java:7984)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1309)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3422)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3601)
at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:85)
at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2066)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loop(Looper.java:223)
at android.app.ActivityThread.main(ActivityThread.java:7656)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:592)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:947)
app_bar_main.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.coordinatorlayout.widget.CoordinatorLayout 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:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<com.google.android.material.appbar.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="@style/Theme.PWorker.AppBarOverlay">
<androidx.appcompat.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
app:popupTheme="@style/Theme.PWorker.PopupOverlay" />
</com.google.android.material.appbar.AppBarLayout>
<include layout="@layout/content_main" />
</androidx.coordinatorlayout.widget.CoordinatorLayout>
依赖项
dependencies {
implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
implementation 'androidx.core:core-ktx:1.6.0'
implementation 'androidx.appcompat:appcompat:1.3.0'
implementation 'com.google.android.material:material:1.4.0'
implementation 'androidx.constraintlayout:constraintlayout:2.0.4'
implementation 'androidx.navigation:navigation-fragment:2.3.5'
implementation 'androidx.navigation:navigation-ui:2.3.5'
implementation 'androidx.lifecycle:lifecycle-livedata-ktx:2.3.1'
implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.3.1'
implementation 'androidx.navigation:navigation-fragment-ktx:2.3.5'
implementation 'androidx.navigation:navigation-ui-ktx:2.3.5'
implementation 'androidx.legacy:legacy-support-v4:1.0.0'
testImplementation 'junit:junit:4.13.2'
androidTestImplementation 'androidx.test.ext:junit:1.1.3'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
//Firebase
implementation platform('com.google.firebase:firebase-bom:28.2.0')
implementation 'com.google.firebase:firebase-analytics-ktx'
implementation 'com.google.firebase:firebase-crashlytics-ktx'
}
我花了很多时间试图在 google 上找到解决方案,但没有任何效果,现在我被困住了。尝试访问 HomeFragment 中的 requireActivity().findNavController(R.id.nav_host_fragment) 时崩溃,但在 MainActivity 中使用与代码片段相同的代码没有崩溃。
非常感谢任何帮助。
您的 activity_main.xml
中似乎没有包含 content_main.xml
I tried to access NavController from the home fragment but had no success.
您无法访问 NavController
,因为您试图在 activity 的 setContentView()
完成之前访问它;即您正在尝试访问尚不存在的资源 R.id.nav_host_fragment
。
原因是 HomeFragment
最初由 activity 托管,并且它是 activity 布局的一部分;为了在 activity 上绘制片段,需要先尝试获取片段布局,然后再使用 setContentView()
返回整个布局
验证是否在 activity (MainActivity
) & HomeFragment
:
中添加了以下日志消息
Activity:
class MainActivity : AppCompatActivity() {
// .... Code omitted
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
Log.d(TAG, "MainActivity onCreate: BEFORE setContentView()")
binding = ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root)
Log.d(TAG, "MainActivity onCreate: AFTER setContentView()")
// .... Code omitted
Log.d(TAG, "MainActivity onCreate: END")
}
片段:
class HomeFragment : Fragment() {
// .... Code omitted
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View {
Log.d(TAG, "HomeFragment onCreateView: START")
homeViewModel =
ViewModelProvider(this).get(HomeViewModel::class.java)
// .... Code omitted
Log.d(TAG, "HomeFragment onCreateView: END")
return root
}
结果:
D/LOG_TAG: MainActivity onCreate: BEFORE setContentView()
D/LOG_TAG: HomeFragment onCreateView: START
D/LOG_TAG: HomeFragment onCreateView: END
D/LOG_TAG: MainActivity onCreate: AFTER setContentView()
D/LOG_TAG: MainActivity onCreate: END
如何解决:
您可以在 onStart()
或 onResume()
中的 HomeFragment
的 onCreateView()
和 onViewCreated()
以外的生命周期方法中设置 navController
class HomeFragment : Fragment() {
// .... Code omitted
override fun onStart() {
super.onStart()
val navController = requireActivity().findNavController(R.id.nav_host_fragment)
}
我尝试从主页片段访问 NavController
但没有成功。花了一整天,但仍然没有成功。该应用程序在 HomeFragment
这行代码中崩溃:
navController = requireActivity().findNavController(R.id.nav_host_fragment)
这是我实现的代码:
HomeFragmnet
class HomeFragment : Fragment() {
private lateinit var homeViewModel: HomeViewModel
private lateinit var recyclerView: RecyclerView
private lateinit var navController: NavController
private var itemList: MutableList<Home?> = ArrayList()
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
navController = requireActivity().findNavController(R.id.nav_host_fragment)
homeViewModel = ViewModelProvider(this).get(HomeViewModel::class.java)
val root = inflater.inflate(R.layout.fragment_home, container, false)
recyclerView = root.findViewById(R.id.homeRecyclerView)
return root
}
}
这是 xml nav_bar.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/nav_home">
<fragment
android:id="@+id/nav_home"
android:name="fi.gambitlabs.pworker.ui.home.HomeFragment"
android:label="@string/menu_home"
tools:layout="@layout/fragment_home" />
</navigation>
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>
content_main.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 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:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior"
tools:showIn="@layout/app_bar_main">
<fragment
android:id="@+id/nav_host_fragment"
android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:defaultNavHost="true"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:navGraph="@navigation/nav_graph" />
</androidx.constraintlayout.widget.ConstraintLayout>
MainActivity
class MainActivity : AppCompatActivity() {
private lateinit var appBarConfiguration: AppBarConfiguration
private lateinit var navController: NavController
private lateinit var navView: NavigationView
override fun onCreate(savedInstanceState: Bundle?) {
// Disable dark mode
AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_NO)
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val toolbar: Toolbar = findViewById(R.id.toolbar)
setSupportActionBar(toolbar)
val drawerLayout: DrawerLayout = findViewById(R.id.drawer_layout)
navView = findViewById(R.id.nav_view)
navController = findNavController(R.id.nav_host_fragment)
// 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), 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)
return navController.navigateUp(appBarConfiguration) || super.onSupportNavigateUp()
}
}
错误日志
E/AndroidRuntime: FATAL EXCEPTION: main
Process: fi.gambitlabs.pworker, PID: 12300
java.lang.RuntimeException: Unable to start activity ComponentInfo{fi.gambitlabs.pworker/fi.gambitlabs.pworker.MainActivity}: android.view.InflateException: Binary XML file line #14 in fi.gambitlabs.pworker:layout/activity_main: Binary XML file line #19 in fi.gambitlabs.pworker:layout/content_main: Error inflating class fragment
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3449)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3601)
at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:85)
at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2066)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loop(Looper.java:223)
at android.app.ActivityThread.main(ActivityThread.java:7656)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:592)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:947)
Caused by: android.view.InflateException: Binary XML file line #14 in fi.gambitlabs.pworker:layout/activity_main: Binary XML file line #19 in fi.gambitlabs.pworker:layout/content_main: Error inflating class fragment
Caused by: android.view.InflateException: Binary XML file line #19 in fi.gambitlabs.pworker:layout/content_main: Error inflating class fragment
Caused by: java.lang.IllegalArgumentException: ID does not reference a View inside this Activity
at android.app.Activity.requireViewById(Activity.java:3375)
at androidx.core.app.ActivityCompat.requireViewById(ActivityCompat.java:366)
at androidx.navigation.Navigation.findNavController(Navigation.java:58)
at *emphasized text*androidx.navigation.ActivityKt.findNavController(Activity.kt:30)
at fi.gambitlabs.pworker.ui.home.HomeFragment.onCreateView(HomeFragment.kt:30)
at androidx.fragment.app.Fragment.performCreateView(Fragment.java:2963)
at androidx.fragment.app.FragmentStateManager.createView(FragmentStateManager.java:518)
at androidx.fragment.app.FragmentStateManager.moveToExpectedState(FragmentStateManager.java:282)
at androidx.fragment.app.FragmentStore.moveToExpectedState(FragmentStore.java:112)
at androidx.fragment.app.FragmentManager.moveToState(FragmentManager.java:1647)
at androidx.fragment.app.FragmentManager.dispatchStateChange(FragmentManager.java:3128)
at androidx.fragment.app.FragmentManager.dispatchViewCreated(FragmentManager.java:3065)
at androidx.fragment.app.Fragment.performViewCreated(Fragment.java:2988)
at androidx.fragment.app.FragmentStateManager.ensureInflatedView(FragmentStateManager.java:392)
at androidx.fragment.app.FragmentStateManager.moveToExpectedState(FragmentStateManager.java:281)
at androidx.fragment.app.FragmentLayoutInflaterFactory.onCreateView(FragmentLayoutInflaterFactory.java:140)
at androidx.fragment.app.FragmentController.onCreateView(FragmentController.java:135)
at androidx.fragment.app.FragmentActivity.dispatchFragmentsOnCreateView(FragmentActivity.java:319)
at androidx.fragment.app.FragmentActivity.onCreateView(FragmentActivity.java:298)
at android.view.LayoutInflater.tryCreateView(LayoutInflater.java:1067)
at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:995)
at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:959)
at android.view.LayoutInflater.rInflate(LayoutInflater.java:1121)
at android.view.LayoutInflater.rInflateChildren(LayoutInflater.java:1082)
at android.view.LayoutInflater.parseInclude(LayoutInflater.java:1261)
at android.view.LayoutInflater.rInflate(LayoutInflater.java:1117)
at android.view.LayoutInflater.rInflateChildren(LayoutInflater.java:1082)
E/AndroidRuntime: at android.view.LayoutInflater.parseInclude(LayoutInflater.java:1261)
at android.view.LayoutInflater.rInflate(LayoutInflater.java:1117)
at android.view.LayoutInflater.rInflateChildren(LayoutInflater.java:1082)
at android.view.LayoutInflater.inflate(LayoutInflater.java:680)
at android.view.LayoutInflater.inflate(LayoutInflater.java:532)
at android.view.LayoutInflater.inflate(LayoutInflater.java:479)
at androidx.appcompat.app.AppCompatDelegateImpl.setContentView(AppCompatDelegateImpl.java:699)
at androidx.appcompat.app.AppCompatActivity.setContentView(AppCompatActivity.java:195)
at fi.gambitlabs.Pworker.MainActivity.onCreate(MainActivity.kt:28)
at android.app.Activity.performCreate(Activity.java:8000)
at android.app.Activity.performCreate(Activity.java:7984)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1309)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3422)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3601)
at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:85)
at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2066)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loop(Looper.java:223)
at android.app.ActivityThread.main(ActivityThread.java:7656)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:592)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:947)
app_bar_main.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.coordinatorlayout.widget.CoordinatorLayout 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:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<com.google.android.material.appbar.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="@style/Theme.PWorker.AppBarOverlay">
<androidx.appcompat.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
app:popupTheme="@style/Theme.PWorker.PopupOverlay" />
</com.google.android.material.appbar.AppBarLayout>
<include layout="@layout/content_main" />
</androidx.coordinatorlayout.widget.CoordinatorLayout>
依赖项
dependencies {
implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
implementation 'androidx.core:core-ktx:1.6.0'
implementation 'androidx.appcompat:appcompat:1.3.0'
implementation 'com.google.android.material:material:1.4.0'
implementation 'androidx.constraintlayout:constraintlayout:2.0.4'
implementation 'androidx.navigation:navigation-fragment:2.3.5'
implementation 'androidx.navigation:navigation-ui:2.3.5'
implementation 'androidx.lifecycle:lifecycle-livedata-ktx:2.3.1'
implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.3.1'
implementation 'androidx.navigation:navigation-fragment-ktx:2.3.5'
implementation 'androidx.navigation:navigation-ui-ktx:2.3.5'
implementation 'androidx.legacy:legacy-support-v4:1.0.0'
testImplementation 'junit:junit:4.13.2'
androidTestImplementation 'androidx.test.ext:junit:1.1.3'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
//Firebase
implementation platform('com.google.firebase:firebase-bom:28.2.0')
implementation 'com.google.firebase:firebase-analytics-ktx'
implementation 'com.google.firebase:firebase-crashlytics-ktx'
}
我花了很多时间试图在 google 上找到解决方案,但没有任何效果,现在我被困住了。尝试访问 HomeFragment 中的 requireActivity().findNavController(R.id.nav_host_fragment) 时崩溃,但在 MainActivity 中使用与代码片段相同的代码没有崩溃。
非常感谢任何帮助。
您的 activity_main.xml
中似乎没有包含 content_main.xmlI tried to access NavController from the home fragment but had no success.
您无法访问 NavController
,因为您试图在 activity 的 setContentView()
完成之前访问它;即您正在尝试访问尚不存在的资源 R.id.nav_host_fragment
。
原因是 HomeFragment
最初由 activity 托管,并且它是 activity 布局的一部分;为了在 activity 上绘制片段,需要先尝试获取片段布局,然后再使用 setContentView()
验证是否在 activity (MainActivity
) & HomeFragment
:
Activity:
class MainActivity : AppCompatActivity() {
// .... Code omitted
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
Log.d(TAG, "MainActivity onCreate: BEFORE setContentView()")
binding = ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root)
Log.d(TAG, "MainActivity onCreate: AFTER setContentView()")
// .... Code omitted
Log.d(TAG, "MainActivity onCreate: END")
}
片段:
class HomeFragment : Fragment() {
// .... Code omitted
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View {
Log.d(TAG, "HomeFragment onCreateView: START")
homeViewModel =
ViewModelProvider(this).get(HomeViewModel::class.java)
// .... Code omitted
Log.d(TAG, "HomeFragment onCreateView: END")
return root
}
结果:
D/LOG_TAG: MainActivity onCreate: BEFORE setContentView()
D/LOG_TAG: HomeFragment onCreateView: START
D/LOG_TAG: HomeFragment onCreateView: END
D/LOG_TAG: MainActivity onCreate: AFTER setContentView()
D/LOG_TAG: MainActivity onCreate: END
如何解决:
您可以在 onStart()
或 onResume()
中的 HomeFragment
的 onCreateView()
和 onViewCreated()
以外的生命周期方法中设置 navController
class HomeFragment : Fragment() {
// .... Code omitted
override fun onStart() {
super.onStart()
val navController = requireActivity().findNavController(R.id.nav_host_fragment)
}