首页 > 解决方案 > 我使用交互式查看器(FLUTTER)时出现手势检测器问题

问题描述

工作: 我正在为书创建应用程序,我正在链接图像并滑动到下一页我正在使用 Gesture Detector 来滑动下一页,我正在使用 InteractiveViewer 来缩放页面

问题: 问题是当我使用捏放大它成功工作但是当拖动页面以查看更多单词时。它检测手势检测器并转到其他页面..

我想要什么: 我想在使用 InteractiveViewer 时禁用手势检测器,比如当我处于放大模式时,手势检测器禁用以及缩小手势检测器启用。

import 'package:flutter/material.dart';

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

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

class _Screen2State extends State<Screen2> {
  @override
  Widget build(BuildContext context) {
    return  Scaffold(
           appBar: appbarr(),
        body: GestureDetector(
          onHorizontalDragUpdate: (details) {  
        // Note: Sensitivity is integer used when you don't want to mess up vertical drag
        int sensitivity = 8;
        int senElse = -8;
        if (details.delta.dx > sensitivity) {
            Navigator.pop(context);
        } 
        else if (details.delta.dx < senElse )
        {
             Navigator.push(context, MaterialPageRoute(builder: (context) => Screen3()));
         }
        },
          child: InteractiveViewer(
            panEnabled: true,
            minScale: 0.5,
            maxScale: 5,
            child: Container(
              width: MediaQuery.of(context).size.width,
              height: MediaQuery.of(context).size.height,
              decoration: BoxDecoration(
              image: DecorationImage(
                image: AssetImage("assets/2.jpg"),
                fit: BoxFit.fill,
              ),
              ),
            ),
          ),
        )
    );
  }
}

标签: flutterdartnative

解决方案


您需要检查用户是否已放大。如果用户放大了,我们不会渲染GestureDetector. 我们只利用GestureDetector了用户没有缩放的情况。要检查用户是否放大,我们使用 aTranformationController并将其当前值与单位矩阵进行比较。

这是工作代码:

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

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

class _Screen2State extends State<Screen2> {
  final transformationController = TransformationController();

  bool get userHasZoomedIn => (Matrix4.identity() - transformationController.value).infinityNorm() > 0.000001;
  
  @override
  Widget build(BuildContext context) {
    final interactiveImage = InteractiveViewer(
      panEnabled: true,
      minScale: 0.5,
      maxScale: 5,
      transformationController: transformationController,
      onInteractionEnd: (details) => setState((){}),
      child: Container(
        width: MediaQuery.of(context).size.width,
        height: MediaQuery.of(context).size.height,
        decoration: BoxDecoration(
          image: DecorationImage(
            image: AssetImage("assets/2.jpg"),
            fit: BoxFit.fill,
          ),
        ),
      ),
    );
    final appBar = AppBar(title: Text('Title'));

    if(userHasZoomedIn){
      return Scaffold(
        appBar: appBar,
        body: interactiveImage,
      );
    }
    
    return Scaffold(
      appBar: appBar,
      body: GestureDetector(
        onHorizontalDragUpdate: (details) {
          // Note: Sensitivity is integer used when you don't want to mess up vertical drag
          int sensitivity = 8;
          int senElse = -8;
          if (details.delta.dx > sensitivity) {
            Navigator.pop(context);
          }
          else if (details.delta.dx < senElse )
          {
            Navigator.push(context, MaterialPageRoute(builder: (context) => Screen3()));
          }
        },
        child: interactiveImage,
      )
    );
  }
}

请注意,我们调用setState. InteractionViewer.onInteractionEnd另一种方法是将侦听器添加到TransformationController

transformationController.addListener(() {
  setState(() {});
});

您不应该这样做,因为这会setState()导致用户体验不佳以及 CPU 和 GPU 负载过高。


推荐阅读