flutter - TabBarView 中的 GestureDetector - 嵌套滚动?

我有一个 TabBarView,其中每个选项卡都包含一个 Image 包装在 GestureDetector 中,用于缩放和平移。如果它很重要,这就是我目前实现缩放的方式:How do I pan and zoom an image? .

现在我遇到的问题是缩放仅在捏合移动非常垂直时才有效。如果我有点偏离,触摸事件会立即用于滑动到下一个选项卡,即使我正在使用两个手指。而且我认为水平平移根本行不通。

Flutter 中是否有任何机制允许内部 GestureDetector 在将它们馈送到 TabBarView 之前拦截某些触摸事件(但不是其他事件,而且并非总是如此)?

最佳答案

如果 Flutter 的平移手势识别器检测到第二个指针向下并且缩放手势识别器处于事件状态,我认为它可能应该让步于缩放手势识别器。如果您同意,请随时为此提出问题。

与此同时,您可以通过在其顶部放置一个不透明的 GestureRecognizer 并将缩放事件转发到您的状态来“禁用”PageView 的平移手势识别器.

import 'package:flutter/material.dart';
import 'package:vector_math/vector_math_64.dart';

void main() {
  runApp(new MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return new MaterialApp(
      title: 'Flutter Demo',
      home: new MyHomePage(),
    );
  }
}

class MyHomePage extends StatelessWidget {
  MyHomePage({Key key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return new DefaultTabController(
      length: 2,
      child: new Scaffold(
        appBar: new AppBar(
          bottom: new TabBar(
            tabs: [
              new Tab(text: 'foo'),
              new Tab(text: 'bar'),
            ],
          ),
        ),
        body: new ScalableTabBarView()
      ),
    );
  }
}

class ScalableTabBarView extends StatelessWidget {

  final List<GlobalKey<ScaledState>> keys = <GlobalKey<ScaledState>>[
    new GlobalKey<ScaledState>(),
    new GlobalKey<ScaledState>(),
  ];

  Widget build(BuildContext context) {
    return new Stack(children: [
      new TabBarView(
        children: [
          new Center(
            child: new Scaled(
              child: new FlutterLogo(),
              key: keys[0],
            ),
          ),
          new Center(
            child: new Scaled(
              child: new FlutterLogo(),
              key: keys[1],
            ),
          ),
        ],
      ),
      new GestureDetector(
        behavior: HitTestBehavior.opaque,
        onScaleStart: (ScaleStartDetails details) {
          keys[DefaultTabController.of(context).index].currentState.onScaleStart(details);
        },
        onScaleUpdate: (ScaleUpdateDetails details) {
          keys[DefaultTabController.of(context).index].currentState.onScaleUpdate(details);
        },
        onScaleEnd: (ScaleEndDetails details)
        {
          keys[DefaultTabController.of(context).index].currentState.onScaleEnd(details);
        }
      ),
    ],
    );
  }
}

class Scaled extends StatefulWidget {
  Scaled({ Key key, this.child }) : super(key: key);

  final Widget child;
  State createState() => new ScaledState();
}

class ScaledState extends State<Scaled> {

  double _previousScale;
  double _scale = 1.0;

  void onScaleStart(ScaleStartDetails details) {
    print(details);
    setState(() {
      _previousScale = _scale;
    });
  }
  void onScaleUpdate(ScaleUpdateDetails details) {
    print(details);
    setState(() {
      _scale = _previousScale * details.scale;
    });
  }
  void onScaleEnd(ScaleEndDetails details) {
    print(details);
    setState(() {
      _previousScale = null;
    });
  }
  @override
  Widget build(BuildContext context) {
    return new GestureDetector(
        child: new Transform(
          transform: new Matrix4.diagonal3(new Vector3(_scale, _scale, _scale)),
          alignment: FractionalOffset.center,
          child: widget.child,
        ),
    );
  }
}

TabBarView 之外处理缩放手势也可用于记住选项卡的缩放状态,而不是在它们离开屏幕时将它们重置为 1.0。

https://stackoverflow.com/questions/43869027/

相关文章:

dart - Flutter Drawer 作为单独的小部件不允许修改宽度

dart - 从 LatLng 列表计算总距离

dart - StreamBuilder 会在无状态小部件中自动关闭流吗?

ios - 如何在 iOS 中安装用 Flutter 编写的应用程序?

dart - Streambuilder 没有收到一些快照数据

dart - 如何在 flutter 中为图标添加阴影?

dart - 在 CustomScrollView 中使用 StreamBuilder 和 Sliv

dart - 在 Flutter 中查找和版本化过时的包(跨主要版本)

flutter - 如何在 Flutter Web 中保存到 Web 本地存储

dart - 在 Flutter 应用程序中存储外观和指标常量