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

Flutter camera包在固定竖屏App中旋转手机出现预览画面拉伸Bug的求助

Flutter camera包在固定竖屏App中旋转手机出现预览画面拉伸Bug的求助

我在自己的App首页的Container组件里集成了pub.dev上的camera包,而且我的App是固定只支持**竖屏(portrait up)**模式的。但测试的时候(用的iPhone 11)发现,当把手机转到横屏方向时,相机预览会试图跟着变成横屏显示,可App本身只支持竖屏,结果就导致Container里的预览画面被严重拉伸变形了,看起来特别奇怪。

我初始化相机控制器的代码大概是类似这样的:

final cameras = await availableCameras();
final selectedCamera = cameras.first;
_controller = CameraController(
  selectedCamera,
  ResolutionPreset.medium,
  enableAudio: false,
);

我之前也踩过这个坑,分享几个亲测有效的解决办法:

  • 强制相机预览锁定竖屏方向
    初始化CameraController时,直接指定固定的竖屏方向,同时确保App的系统配置确实锁定了竖屏:

    _controller = CameraController(
      selectedCamera,
      ResolutionPreset.medium,
      enableAudio: false,
      orientation: DeviceOrientation.portraitUp, // 强制竖屏
    );
    

    系统配置方面:

    • iOS:在Info.plist里的UISupportedInterfaceOrientations数组中,只保留UIInterfaceOrientationPortrait;
    • Android:在AndroidManifest.xml的对应activity标签里添加android:screenOrientation="portrait"。
  • 用Transform组件修正画面拉伸
    如果相机自带的方向设置没起效果,可以用Transform组件调整预览画面的旋转和比例,让它完美适配Container:

    Container(
      width: 300, // 你的Container宽度
      height: 400, // 你的Container高度
      child: AspectRatio(
        aspectRatio: _controller.value.aspectRatio,
        child: Transform(
          alignment: Alignment.center,
          // 根据相机传感器方向调整旋转角度,确保画面正立
          transform: Matrix4.rotationZ(_getRotationAngle()),
          child: CameraPreview(_controller),
        ),
      ),
    )
    

    其中_getRotationAngle()可以根据相机的传感器方向计算:

    double _getRotationAngle() {
      switch (_controller.value.sensorOrientation) {
        case 90:
          return -math.pi / 2;
        case 270:
          return math.pi / 2;
        default:
          return 0;
      }
    }
    
  • 监听设备方向变化,动态适配尺寸
    虽然App锁定了竖屏,但设备物理方向还是会变化,我们可以监听这个变化,动态刷新预览的适配状态:

    @override
    void initState() {
      super.initState();
      WidgetsBinding.instance.addObserver(this);
    }
    
    @override
    void dispose() {
      WidgetsBinding.instance.removeObserver(this);
      _controller.dispose();
      super.dispose();
    }
    
    @override
    void didChangeMetrics() {
      super.didChangeMetrics();
      // 刷新UI,让预览重新适配Container尺寸
      setState(() {});
    }
    

备注:内容来源于stack exchange,提问作者dkaangulhan

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.13 16:33:18