Flutter Camera插件:如何将拍摄方向锁定为landscapeRight或landscapeLeft?
Flutter Camera插件横屏双方向适配方案
你的问题核心是lockCaptureOrientation固定单一方向后,另一种横屏模式下相机流与UI方向不匹配。解决方案是根据设备实时横屏方向动态调整相机捕获方向,而非锁定单一方向,具体实现如下:
1. 监听设备方向变化,动态锁定相机捕获方向
通过Flutter原生的方向监听机制,在设备切换横屏方向时,同步更新相机的捕获方向:
class CameraScreen extends StatefulWidget { const CameraScreen({super.key}); @override State<CameraScreen> createState() => _CameraScreenState(); } class _CameraScreenState extends State<CameraScreen> with WidgetsBindingObserver { CameraController? _controller; DeviceOrientation? _currentOrientation; @override void initState() { super.initState(); _initCamera(); // 注册方向变化监听 WidgetsBinding.instance.addObserver(this); } @override void dispose() { // 移除监听,避免内存泄漏 WidgetsBinding.instance.removeObserver(this); _controller?.dispose(); super.dispose(); } // 监听设备方向变化 @override void didChangeMetrics() { super.didChangeMetrics(); final currentDeviceOrientation = WidgetsBinding.instance.window.orientation; // 仅处理横屏方向的切换 if ([DeviceOrientation.landscapeLeft, DeviceOrientation.landscapeRight].contains(currentDeviceOrientation)) { if (currentDeviceOrientation != _currentOrientation) { _currentOrientation = currentDeviceOrientation; // 动态更新相机捕获方向 _controller?.lockCaptureOrientation(currentDeviceOrientation); setState(() {}); } } } // 初始化相机控制器 Future<void> _initCamera() async { final cameras = await availableCameras(); final targetCamera = cameras.first; // 根据需求选择前置/后置相机 _controller = CameraController( targetCamera, ResolutionPreset.high, ); await _controller?.initialize(); // 初始化时锁定当前设备横屏方向 final initialOrientation = WidgetsBinding.instance.window.orientation; if ([DeviceOrientation.landscapeLeft, DeviceOrientation.landscapeRight].contains(initialOrientation)) { _currentOrientation = initialOrientation; await _controller?.lockCaptureOrientation(initialOrientation); } setState(() {}); } @override Widget build(BuildContext context) { if (_controller == null || !_controller!.value.isInitialized) { return const Center(child: CircularProgressIndicator()); } return AspectRatio( aspectRatio: _controller!.value.aspectRatio, child: CameraPreview(_controller!), ); } }
2. 保持main函数的横屏设置不变
继续保留你原来的全局横屏配置,确保应用仅允许横屏模式:
void main() async { WidgetsFlutterBinding.ensureInitialized(); await SystemChrome.setPreferredOrientations([ DeviceOrientation.landscapeRight, DeviceOrientation.landscapeLeft, ]); runApp(const MyApp()); }
关键说明
- 该方案会在设备切换横屏方向时,自动同步相机的捕获方向,保证相机流与UI方向一致,两种横屏模式均能正常工作。
- 建议在真实设备上测试,模拟器的方向切换可能存在延迟或异常。
内容的提问来源于stack exchange,提问作者Georgian Sarghi
相关产品推荐
相关产品推荐

