Flutter 相机捏合缩放

Flutter Camera pinch zoom

我正在尝试在 Flutter 中创建一个相机应用程序,但我一直遇到缩放问题。 我设法让缩放代码通过按钮工作,但是当我尝试用 GestureDetector 替换这些按钮时,没有任何反应。

下面是相机页面。我尝试通过添加 debugLog 来检查我的 gestureDetector 是否在某处被调用,但这不会打印任何内容,所以我认为问题出在调用检测器上,而不一定是检测器内的代码


class CameraPreviewPage extends StatefulWidget {
  final CameraDescription camera;

  CameraPreviewPage({required this.camera});

  @override
  _CameraPreviewPageState createState() => _CameraPreviewPageState();
}

class _CameraPreviewPageState extends State<CameraPreviewPage> {
  late CameraController _cameraController;
  late Future<void> _initializeCameraControllerFuture;
  double zoom = 1.0;
  double _scaleFactor = 1.0;

  @override
  void initState() {
    super.initState();

    _cameraController =
        CameraController(widget.camera, ResolutionPreset.ultraHigh);

    _initializeCameraControllerFuture = _cameraController.initialize();
  }

  @override
  Widget build(BuildContext context) {
    return Stack(
      children: <Widget>[
       FutureBuilder(
            future: _initializeCameraControllerFuture,
            builder: (context, snapshot) {
              //The gestureDetector doesn't work
              if (snapshot.connectionState == ConnectionState.done) {
                return
                  GestureDetector(
                    behavior: HitTestBehavior.translucent,
                    onScaleStart: (details) {
                       zoom = _scaleFactor;
                    },
                    onScaleUpdate: (details) {
                       _scaleFactor = zoom * details.scale;
                       _cameraController.setZoomLevel(_scaleFactor);
                       debugPrint('Gesture updated');
                    },
                    child:CameraPreview(_cameraController));
              } else {
                return Center(child: CircularProgressIndicator());
              }
            },
          ),

        SafeArea(
            child: Scaffold(
          backgroundColor: Colors.transparent,
          floatingActionButton:
              Column(mainAxisSize: MainAxisSize.min, children: <Widget>[
            FloatingActionButton(
              heroTag: "FABZoomIn",
              child: Icon(
                Icons.zoom_in,
                color: Colors.white,
              ),
              onPressed: () {
                if (zoom < 8) {
                  zoom = zoom + 1;
                }
                _cameraController.setZoomLevel(zoom);
              },
              backgroundColor: Colors.cyan,
            ),
            SizedBox(
              height: 10,
            ),
            FloatingActionButton(
              heroTag: "FABZoomOut",
              child: Icon(
                Icons.zoom_out,
                color: Colors.white,
              ),
              onPressed: () {
                if (zoom > 1) {
                  zoom = zoom - 1;
                }
                _cameraController.setZoomLevel(zoom);
              },
              backgroundColor: Colors.red,
            ),
            SizedBox(
              height: 10,
            ),
            FloatingActionButton(
                heroTag: "FABCamera",
                child: Icon(Icons.camera, color: Colors.white),
                backgroundColor: Colors.green,
                onPressed: () {
                  _takePicture(context);
                })
          ]),
        ))
      ],
    );
  }

  @override
  void dispose() {
    _cameraController.dispose();
    super.dispose();
  }
}

编辑:我也尝试过使用 onTap 看看这是否让我对可能出现的问题有了更多的了解,但 onTap 也没有注册。

发生这种情况是因为 Stackchildren 内的第一个 child 首先呈现,所有其他 children 都呈现在第一个 child.

因此,您的 GestureDetector 将永远不会触发,因为另一个 children 正在处理点击并阻止 GestureDetector 接收任何点击。

只需将您的 GestureDetector 移动到 children 列表的末尾。

Stack(
  children: [
    SafeArea(
      ....
    ), 
    GestureDetector(
      ....
    ),
  ],
)

如果您确实需要底部的 CameraPreview 和顶部呈现的 SafeArea,则将您的 CameraPreview 分成另一个 Container 并让您的GestureDetector 作为 children 列表末尾的单独小部件。

Stack(
  children: [
    Container(
      child: CameraPreview(),
    ),
    SafeArea(
      ....
    ), 
    GestureDetector(
      ....
    ),
  ],
)