如何在 Android Jetpack 导航中创建动态起始目的地

Ily*_*man 14 navigation android android-jetpack

我正在构建一个 SMS 应用程序,使用Android Jetpack中的导航包在屏幕之间导航。

当用户第一次打开我的应用程序时,他们会进入权限屏幕,在该屏幕上他们需要授予默认应用程序权限和一些常规权限,然后才能进入主屏幕。

当用户更改默认短信应用程序然后重新打开我的应用程序时,我还需要显示权限屏幕。

我在 Android 导航文档中看到了条件导航部分。它建议将此逻辑放在主屏幕片段onViewCreated方法中。但我担心它会影响我的应用程序的启动时间。

有没有更有效的方法来实现这一点?理想情况下,我想在活动中处理这个逻辑。

Key*_*öze 26

不要在 XML 文件中设置导航图。

<?xml version="1.0" encoding="utf-8"?>
<androidx.fragment.app.FragmentContainerView 
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/navigationHostFragmentMain"
    android:name="androidx.navigation.fragment.NavHostFragment"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    app:defaultNavHost="true" />
Run Code Online (Sandbox Code Playgroud)

在您中,Activity您可以以编程方式设置起始目的地,然后设置导航图。

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)

    setNavigationGraph()
}

private fun setNavigationGraph() {
    val navHostFragment =
        supportFragmentManager.findFragmentById(R.id.navigationHostFragmentMain) as NavHostFragment
    val navController = navHostFragment.navController

    val navGraph = navController.navInflater.inflate(R.navigation.navigation_graph)
    navGraph.startDestination =
        if (viewModel.isLoggedIn) {
            R.id.homeFragment
        } else {
            R.id.loginFragment
        }

    navController.graph = navGraph
}
Run Code Online (Sandbox Code Playgroud)

  • 请注意,每次在“onCreate”中显式设置 navGraph 将导致一个新的“导航实例”,例如,在方向更改后,您回到(可能经过调整的)起始目的地,这可能不是您想要的。作为解决方案,您只能在第一次设置图表,因此当“savedInstanceState == null”时 (3认同)
  • 它会导致崩溃并出现错误原因:java.lang.IllegalStateException:没有通过 app:startDestination 定义启动目标 (3认同)
  • 你测试过吗?如果配置更改导致重新创建活动,那么“Activity”的视图将再次膨胀,在这种情况下,我们将不得不再次设置图表,因为我们没有在“XML”文件中这样做?也许重用导航图而不是每次都膨胀它是有意义的。我不知道。如果你还没有,我会测试一下。 (2认同)
  • 啊抱歉,我错过了您不再在布局 xml 中设置图表。仅当您另外在 xml 中设置了图表时,才会出现我所描述的问题。如果您只在“onCreate”中设置它,那么即使更改配置也可以。 (2认同)

Pet*_*báč 7

您可以像这样以编程方式设置图形的 startDestination

val graph = findNavController(R.id.YOUR_CONTAINER_ID).graph
graph.startDestination = R.id.ID_OF_THE_FRAGMENT_FOR_START_DESTINATION
findNavController(R.id.YOUR_CONTAINER_ID).setGraph(graph)
Run Code Online (Sandbox Code Playgroud)

这可以在 Activity 的 onCreate() 方法中执行