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

Android开发:如何在Fragment中锁定屏幕为横屏方向

Fragment场景下锁定屏幕方向实现方案

单Activity架构下,屏幕方向控制本身就是Activity的职责,Fragment不需要自己实现方向控制逻辑,有两种成熟的实现方式,完全适配你当前的导航链路。


方案1:直接在Fragment生命周期中调用宿主Activity方法(最推荐,适配单Activity架构)

你不需要写额外的通信逻辑,直接在GameFragment的对应生命周期节点读取配置、调用Activity的方向设置方法即可,核心是要记得在离开GameFragment时恢复默认方向,避免其他页面被强制横屏。
示例代码(Kotlin,Java逻辑完全一致):

class GameFragment : Fragment() {
    override fun onResume() {
        super.onResume()
        // 读取本地存储的应用设置,判断是否需要锁定横屏
        val shouldLockLandscape = requireContext().getSharedPreferences("app_config", Context.MODE_PRIVATE)
            .getBoolean("lock_land_when_play", false)
        
        if (shouldLockLandscape) {
            // 直接调用宿主Activity的方向设置方法
            requireActivity().requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE
        } else {
            // 不需要锁的话保持跟随系统传感器
            requireActivity().requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED
        }
    }

    override fun onPause() {
        super.onPause()
        // 离开GameFragment时必须恢复默认方向,否则回到MainFragment/GameSetupFragment时会保持横屏
        requireActivity().requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED
    }
}

注意:如果你的Manifest中给Activity配置了android:configChanges="orientation|screenSize",该方案依然生效,不会触发Activity重建。


方案2:接口解耦实现(适配后续可能扩展多Activity的场景)

如果你不希望Fragment直接依赖Activity的具体实现,可以定义通用的方向控制接口,让宿主Activity实现该接口,Fragment在绑定上下文时获取接口实例调用即可,耦合度更低。

  1. 先定义通用控制接口:
interface ScreenOrientationController {
    fun lockToLandscape()
    fun restoreDefault()
}
  1. 让你的宿主MainActivity实现该接口:
class MainActivity : AppCompatActivity(), ScreenOrientationController {
    override fun lockToLandscape() {
        requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE
    }

    override fun restoreDefault() {
        requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED
    }
}
  1. 在GameFragment中通过接口调用:
class GameFragment : Fragment() {
    private var orientationController: ScreenOrientationController? = null

    override fun onAttach(context: Context) {
        super.onAttach(context)
        // 绑定宿主实现的控制器
        orientationController = context as? ScreenOrientationController
    }

    override fun onDetach() {
        super.onDetach()
        orientationController = null
    }

    override fun onResume() {
        super.onResume()
        val shouldLockLandscape = // 读取你的设置项
        if (shouldLockLandscape) {
            orientationController?.lockToLandscape()
        } else {
            orientationController?.restoreDefault()
        }
    }

    override fun onPause() {
        super.onPause()
        orientationController?.restoreDefault()
    }
}

适配你当前导航链路的注意事项

  • 不管是从MainFragment直接跳转GameFragment,还是经过GameSetupFragment中转再跳转,上述两个方案都能正常生效,Fragment生命周期会随着导航切换正常触发
  • 不要在GameFragment的onCreate生命周期中设置方向,Navigation组件切换Fragment时前一个页面的销毁存在延迟,在onResume中设置时机最准确
  • 如果你在GameSetupFragment中提供了横屏锁定的开关选项,只需要把开关状态通过Navigation的参数Bundle传给GameFragment,GameFragment读取参数判断是否锁横屏即可

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.30 21:06:22