You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

屏幕旋转时如何加载对应UI?使用Navigation Controller加载Fragment的实现问题

解决方案

问题根源

  • 你混用了supportFragmentManager直接操作Navigation托管的容器,和NavController的栈管理逻辑冲突
  • 切回竖屏时仅重新绑定了ActionBar,没有清理横屏模式下手动添加的Fragment,导致多层Fragment叠加显示

实现步骤

1. 配置方向限定布局

首先在res目录下创建两个布局文件夹:

  • res/layout-port:存放竖屏模式的主布局,仅保留单个NavHostFragment容器,id为nav_host_fragment_content_main
  • res/layout-land:存放横屏模式的主布局,添加两个独立的Fragment容器,id分别为left_container、right_container

同时确认你已在AndroidManifest.xml对应Activity节点添加配置,避免旋转时Activity重建:

<activity
    android:name=".YourActivity"
    android:configChanges="orientation|screenSize|screenLayout" />

2. 修正配置变更逻辑

替换你原来的onConfigurationChanged代码,核心逻辑是横屏时手动管理两个Fragment,竖屏时先清理手动添加的Fragment再恢复Navigation托管:

override fun onConfigurationChanged(newConfig: Configuration) {
    super.onConfigurationChanged(newConfig)
    val navController = findNavController(R.id.nav_host_fragment_content_main)
    if (newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE) {
        // 先获取当前Navigation栈顶的Fragment(即竖屏正在显示的页面)
        val currentFragment = supportFragmentManager.findFragmentById(R.id.nav_host_fragment_content_main)
            ?.childFragmentManager?.primaryNavigationFragment
        // 隐藏NavHost避免叠加
        supportFragmentManager.findFragmentById(R.id.nav_host_fragment_content_main)?.view?.visibility = View.GONE
        // 横屏加载两个Fragment
        supportFragmentManager.beginTransaction()
            .replace(R.id.left_container, currentFragment ?: FirstFragment())
            .replace(R.id.right_container, SecondFragment()) // 替换为你要展示的第二个Fragment
            .commit()
    } else {
        // 先移除横屏时添加的所有Fragment
        supportFragmentManager.findFragmentById(R.id.left_container)?.let {
            supportFragmentManager.beginTransaction().remove(it).commit()
        }
        supportFragmentManager.findFragmentById(R.id.right_container)?.let {
            supportFragmentManager.beginTransaction().remove(it).commit()
        }
        // 恢复NavHost显示和ActionBar绑定
        supportFragmentManager.findFragmentById(R.id.nav_host_fragment_content_main)?.view?.visibility = View.VISIBLE
        appBarConfiguration = AppBarConfiguration(navController.graph)
        setupActionBarWithNavController(navController, appBarConfiguration)
    }
}

注意事项

  • 不要直接操作NavHostFragment内部的容器,会破坏Navigation的栈管理逻辑
  • 切换方向时必须清理非Navigation托管的Fragment实例,避免重叠
  • 若需要保留Fragment状态,可以通过ViewModel存储页面数据,切换时直接复用实例即可

内容的提问来源于stack exchange,提问作者Prashant Gosai

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.01 20:57:02