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

Flutter平板相机初始化时屏幕强制旋转问题求助

问题描述

我正在开发一款适配7英寸及以上平板的Flutter应用,登录完成后启动相机功能,需要同时录制视频并在屏幕角落以小窗口形式显示相机预览。

问题:在Android Studio的所有平板模拟器中,初始化相机(尚未开始录制视频)时,应用会自动改变屏幕方向,并显示“Rotate for a better view”提示。目前尚未在真机上测试该问题。


相关代码
  1. 应用启动时锁定横屏方向:
void main() async {
  SystemChrome.setPreferredOrientations(
        [DeviceOrientation.landscapeLeft, DeviceOrientation.landscapeRight])
    .then((_) {
    runApp(MyApp(prefs));
  });
}
  1. 相机控制器初始化代码:
void initState() {
  super.initState();
  SystemChrome.setPreferredOrientations([
    DeviceOrientation.landscapeLeft,
    DeviceOrientation.landscapeRight,
  ]);
  WidgetsBinding.instance.addPostFrameCallback((_) async {
    Timer(
      const Duration(seconds: 1),
      () async {
        await _initCamera();
        // await _recordVideo();
      },
    );
  });
}

_initCamera() async {
  final cameras = await availableCameras();

  final CameraDescription camera = cameras
          .where(
              (camera) => camera.lensDirection == CameraLensDirection.front)
          .firstOrNull ??
      cameras.first;

  _cameraController = CameraController(
    camera,
    ResolutionPreset.max,
    enableAudio: true,
  );
  await _cameraController!.initialize().then((_) {
    if (!mounted) {
      return;
    }
    setState(() {});
  });

  await _cameraController!.lockCaptureOrientation(DeviceOrientation.landscapeRight);

  _isLoading = false;
  isCamera = true;
  setState(() {});
}
  1. 角落相机预览Widget代码:
Container(
    padding: const EdgeInsets.all(4),
    decoration: BoxDecoration(
        color: isCamera
            ? isCameraRecording
                ? Colors.deepOrange
                : Colors.black
            : Colors.redAccent,
        borderRadius: const BorderRadius.all(Radius.circular(10))),
    child: isCamera && _cameraController != null
        ? CameraPreview(_cameraController!)
        : null,
)

解决办法

1. 强制Android原生Activity固定横屏

Android系统相机服务可能会优先使用自身最优拍摄方向,覆盖Flutter的方向设置。修改android/app/src/main/AndroidManifest.xml,在对应<activity>标签中添加:

android:screenOrientation="landscape"
android:configChanges="orientation|screenSize|keyboardHidden"

通过原生配置强制Activity保持横屏,避免系统相机触发方向变更。

2. 调整相机初始化与方向锁定顺序

将拍摄方向锁定操作移到相机初始化之前,避免相机启动时临时切换方向:

_initCamera() async {
  final cameras = await availableCameras();
  final CameraDescription camera = cameras
          .where((camera) => camera.lensDirection == CameraLensDirection.front)
          .firstOrNull ?? cameras.first;

  _cameraController = CameraController(
    camera,
    ResolutionPreset.max,
    enableAudio: true,
  );

  // 先锁定拍摄方向,再执行初始化
  await _cameraController!.lockCaptureOrientation(DeviceOrientation.landscapeRight);
  await _cameraController!.initialize().then((_) {
    if (!mounted) return;
    setState(() {});
  });

  _isLoading = false;
  isCamera = true;
  setState(() {});
}

3. 移除不必要的延迟与重复设置

initState中的1秒延迟可能给系统留出触发方向变更的时间,直接移除Timer调用:

WidgetsBinding.instance.addPostFrameCallback((_) async {
  await _initCamera();
  // await _recordVideo();
});

同时,main函数已完成方向锁定,可删除initState中重复的SystemChrome.setPreferredOrientations调用,避免配置冲突。

4. 模拟器环境优化

部分模拟器的传感器模拟存在异常,可尝试:

  • 关闭模拟器快捷设置中的「自动旋转」功能
  • 切换不同Android版本的模拟器镜像测试(如从Android 14切换到Android 13)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.16 08:40:19