android - IllegalStateException: Activity 没有设置 NavController
问题描述
我尝试编写一个 Android 应用程序,它使用来自 androidx 的导航组件、工具栏和抽屉布局从左侧滑入设置菜单。我按照指南开始使用 Navigation 组件并尝试使用本指南使用 NavigationUI 更新 UI 组件来添加顶部应用栏和设置。
当我的应用程序启动时,会引发以下异常:
java.lang.IllegalStateException: Activity ....MainActivity@e686cd8 does not have a NavController set on 2131230993
旁注:如果我nav_graph.xml
在设计模式下打开,主机窗格会报告“未找到 NavHostFragments。此导航图必须从布局中的 NavHostFragment 引用才能访问。” 也许这个错误和异常是相关的并且共享相同的根本原因。但是,我的导航图被 aNavHostFragment
虽然引用,见下文。
活动主.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:context=".MainActivity">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<androidx.appcompat.widget.Toolbar
android:id="@+id/main_toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
android:theme="?attr/actionBarTheme" />
<androidx.fragment.app.FragmentContainerView
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:navGraph="@navigation/nav_graph" />
</LinearLayout>
<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:menu="@menu/drawer_view"
app:headerLayout="@layout/nav_header" />
</androidx.drawerlayout.widget.DrawerLayout>
这种布局
- 包含一个
FragmentContainerView
- 参考资料
@navigation/nav_graph
(粘贴在下面) - 包含一个
NavigationView
- 参考资料
@layout/nav_header
(粘贴在下面) - 参考资料
@menu/drawer_view
(粘贴在下面)
nav_header.xml:
<?xml version="1.0" encoding="utf-8"?>
<android.widget.LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="192dp"
android:background="?attr/colorPrimaryDark"
android:gravity="bottom"
android:padding="16dp"
android:theme="@style/ThemeOverlay.AppCompat.Dark">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/app_name"
android:textAppearance="@style/TextAppearance.AppCompat.Body1" />
</android.widget.LinearLayout>
抽屉视图.xml:
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<group android:checkableBehavior="single">
<item
android:id="@+id/nav_home"
android:icon="@drawable/ic_home"
android:title="@string/home"/>
<item
android:id="@+id/nav_settings"
android:icon="@drawable/ic_settings"
android:title="@string/settings" />
</group>
</menu>
片段主页.xml:
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".HomeFragment"/>
该片段被nav_graph
(粘贴在下面)作为主片段(起始目的地)引用。
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/homeFragment">
<fragment
android:id="@+id/homeFragment"
android:name="de.mhnnet.lychee4android.HomeFragment"
android:label="fragment_home"
tools:layout="@layout/fragment_home" />
</navigation>
MainActivity.java:
protected void onCreate( Bundle savedInstanceState ) {
super.onCreate( savedInstanceState );
setContentView( R.layout.activity_main );
NavController navController = Navigation.findNavController(this, R.id.nav_host_fragment );
AppBarConfiguration appBarConfiguration =
new AppBarConfiguration.Builder(navController.getGraph()).build();
Toolbar toolbar = findViewById( R.id.main_toolbar );
NavigationUI.setupWithNavController( toolbar, navController, appBarConfiguration );
}
进一步说明:
我已经找到了一些提示androidx.fragment.app.FragmentContainerView
应该替换为fragment
. 但是,这感觉不对,因为 linter 建议使用FragmentContainerView
而不是fragment
官方Android 文档也使用FragmentContainerView
。
解决方案
可以Nav Controller
参加您的活动,或者更换您的
<androidx.fragment.app.FragmentContainerView
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:navGraph="@navigation/nav_graph" />
和
<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:navGraph="@navigation/nav_graph" />
FragmentContainerView
但正如 lint 建议使用以下代码更改片段以进入Nav Controller
您的活动。
NavHostFragment navHostFragment = (NavHostFragment) getSupportFragmentManager().findFragmentById(R.id.nav_host_fragment);
if (navHostFragment != null) {
NavController navController = navHostFragment.getNavController();
// Setup NavigationUI here
}
推荐阅读
- angular - Angular:拦截器抛出错误后如何检查类类型
- autotools - Autotools ./configure 在 config.status 期间失败:由于 MKDIR_P 定义不正确,在 alpine 中执行 depfiles 命令
- powershell - 使用 whenChanged 属性删除的用户
- laravel - 升级到 5.8 后 IoC 解决问题
- pygame - Pygame屏幕颜色不会填充,直到屏幕移到开始菜单下方?
- r - 为什么一定要用“。” 将 dplyr 与 ggplot 结合时?
- html - 我的电子邮件模板中有两个 mailto 链接,并希望有两种不同的颜色。(蓝色和白色)
- spring-boot - 调试不适用于 Spring Boot 2.2 和 IntelliJ Idea
- c++ - C++ istream.get() 提取后返回换行符
- testing - Flutter 集成测试中的平台特定代码