从Compose导航到Fragment

5

我希望能够从Compose导航到一个Fragment。我已经在Compose中定义了一个NavHost:

NavHost(
   navController = navController,
   startDestination = DrawerScreen.Screen2.route
) {
   composable(DrawerScreen.Screen1.route) {
      navController.navigate(R.id.screen_one)
   }
   composable(DrawerScreen.Screen2.route) {
      Screen2(
         openDrawer = {
            openDrawer()
         }
      )
   }
}

简单的片段:

@AndroidEntryPoint
class ScreenOneFragment: Fragment() {

   @Nullable
   override fun onCreateView(
      inflater: LayoutInflater,
      @Nullable container: ViewGroup?,
      @Nullable savedInstanceState: Bundle?
   ): View {
      val view: View = inflater.inflate(R.layout.screen_one, container, false)
      return view
   }
}

然而,当我尝试导航时,出现以下异常:
java.lang.IllegalArgumentException: Navigation action/destination com.test/screenOne cannot be found from the current destination Destination(0x2b264dff) route=ScreenOne

这是我的导航XML:

<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/mobile_navigation"
    app:startDestination="@id/screenOne">
    <fragment
        android:id="@+id/screenOne"
        android:name="com.test.ScreenOne"
        android:label="ScreenOne" />
</navigation>

从compose到Fragment是否可以导航?


你不能在片段中使用Compose导航器。你需要使用视图系统导航器,并将你的组合内容托管在片段中。 - Francesc
@Francesc 我真的希望这不是真的。我的应用程序99%都是Compose,我只需要一个Fragment。看起来像是一个巨大的疏忽。 - lostintranslation
@ianhanniballake 主要是因为我正在创建的片段是一个复杂的地图片段。最好创建一个Android Fragment并使用非Compose函数来分解逻辑。另外,是否可以从NavHost可组合函数调用AndroidViewBinding? - lostintranslation
在可组合的目标内,您可以做任何想做的事情,包括创建复杂的地图片段 :) - ianhanniballake
@ianhanniballake,所以看起来我的问题的答案是否定的。 - lostintranslation
显示剩余3条评论
1个回答

8
根据互操作性文档
如果您想将Navigation组件与Compose一起使用,有两个选项: 1. 为片段(fragments)使用Navigation组件定义导航图。 2. 使用Compose目标在Compose中使用NavHost定义导航图。只有所有屏幕都是可组合的时候才可以这样做。
因此,如果您正在使用NavHost,则不能导航到片段目标(反之亦然:如果您正在使用NavHostFragment,则无法导航到可组合目标:两者都不知道对方)。
实际上听起来像是您想向Compose添加一个Fragment。 这将允许您的单个NavHost中的所有目标都成为可组合目标,但可以通过片段(fragment)实现一个屏幕(例如您的ScreenOne)。
composable(DrawerScreen.Screen1.route) {
  // Assumes you have a layout with a FragmentContainerView
  // that uses android:name="com.test.ScreenOneFragment"
  AndroidViewBinding(ScreenOneLayoutBinding::inflate) {
    val myFragment = fragmentContainerView.getFragment<ScreenOneFragment>()
    // ...
}

}


1
当尝试导航到此目标时,会导致崩溃:android.view.InflateException: Binary XML file line #2 in .... Error inflating class androidx.fragment.app.FragmentContainerView。有什么想法是什么问题?导航到纯组合目标正常工作,XML 中没有实际问题,并且我正在使用唯一的 ID。 - NoHarmDan
1
@NoHarmDan,如果您想使用AndroidViewBinding,则需要将AppCompatActivity作为基本活动。如果在使用AppCompatActivity后出现崩溃,请检查您的主题并进行修复。 - shaktiman_droid

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接