在 Flutter 中方向改变时旋转小部件(但保持布局位置)

Rotate Widget When Orientation Changes in Flutter (But Keeping The Layout Position)

我正在创建一个自然需要支持纵向和横向方向的相机应用程序。

是否可以在不更改小部件布局位置的情况下旋转小部件? (它们仍然在原位,但图标会根据当前方向旋转,就像普通的相机应用程序行为一样)

有什么想法吗?

肖像

风景

风景

不幸的是,flutter 无法检测像 纵向向上纵向向下

这样的方向

所以我们需要一个包来帮助实现这个行为native_device_orientation

1- 您需要将屏幕方向锁定为 portraitUp
2- 现在我们应该依靠 传感器数据 来让设备在不旋转应用程序的情况下获得正确的方向。 native_device_orientation 将帮助我们实现
3- 使用 RotatedBox or Transform.rotate 根据需要对当前屏幕方向作出反应

完整的工作示例

import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:native_device_orientation/native_device_orientation.dart';

void main(List<String> args) async {
  WidgetsFlutterBinding.ensureInitialized();
  await SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp]); // -->[1]
  runApp(const App());
}

class App extends StatelessWidget {
  const App({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return const MaterialApp(
      home: Home(),
    );
  }
}

class Home extends StatefulWidget {
  const Home({Key? key}) : super(key: key);

  @override
  State<Home> createState() => _HomeState();
}

class _HomeState extends State<Home> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: NativeDeviceOrientationReader(
          useSensor: true, // --> [2]
          builder: (ctx) {
            final orientation = NativeDeviceOrientationReader.orientation(ctx);
            int turns = 0;
            switch (orientation) {
              case NativeDeviceOrientation.portraitUp:
                turns = 0;
                break;
              case NativeDeviceOrientation.portraitDown:
                turns = 2;
                break;
              case NativeDeviceOrientation.landscapeLeft:
                turns = 1;
                break;
              case NativeDeviceOrientation.landscapeRight:
                turns = 3;
                break;
              case NativeDeviceOrientation.unknown:
                turns = 0;
                break;
            }
            // --> [3]
            return RotatedBox( 
              quarterTurns: turns,
              child: const Icon(
                Icons.abc,
                size: 100,
              ),
            );
          },
        ),
      ),
    );
  }
}