Flutter 中的原始 touch/swipe 数据?与 Java w/ Android Studio 相比?

Raw touch/swipe data in Flutter? Compared to Java w/ Android Studio?

我是 Flutter 开发的新手,我必须很快决定它是否适合我的实习项目。

我必须创建一个界面,它需要所有方向的滑动才能导航到不同的菜单(我正在考虑进行嵌套的水平和垂直滚动,我在 Android Studio 中遇到过问题)- 但是更重要的是,我必须保存来自 touching/tapping/swiping 的原始数据。我不能只保存 "left swipe" 或 "right swipe",我还必须知道压力、速度、位置、确切路径等

这在flutter中可行吗?与 Android studio 相比,flutter 如何处理这些原始数据? flutter 是否只确定滑动的大致方向,仅此而已?

我找了一整天的答案,但我一定是遗漏了一些关键词,因为我一直找不到答案。

您可以使用 Listener 获得原始触摸动作。以下示例显示如何获取点列表。它使用它们来绘制您刚刚用手指描绘的线条。你不能说出压力,但可以说出确切的路径和速度(如果你存储了每个点的时间)。更高级别的检测器 GestureDetector 向您隐藏了这些原始动作,但将它们解释为传统的滑动。

(关于示例的注释...shouldRepaint 应该更聪明,Listener 返回的点在全局坐标中,因此可能需要转换为本地坐标(这个简单的示例有效,因为没有 AppBar) )

import 'package:flutter/material.dart';

void main() => runApp(new MyApp());

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

class MyHomePage extends StatefulWidget {
  @override
  _MyHomePageState createState() => new _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  List<Offset> points = [];

  @override
  Widget build(BuildContext context) {
    return new Scaffold(
      body: new Listener(
        onPointerDown: (e) {
          points = [];
          points.add(e.position);
        },
        onPointerMove: (e) {
          points.add(e.position);
        },
        onPointerUp: (e) {
          points.add(e.position);
          setState(() {});
        },
        child: new CustomPaint(
          painter: new PathPainter(points),
          child: new Container(
            width: 300.0,
            height: 300.0,
            color: Colors.black12,
          ),
        ),
      ),
    );
  }
}

class PathPainter extends CustomPainter {
  List<Offset> points;
  Path path = new Path();

  PathPainter(this.points) {
    if (points.isEmpty) return;
    Offset origin = points[0];
    path.moveTo(origin.dx, origin.dy);
    for (Offset o in points) {
      path.lineTo(o.dx, o.dy);
    }
  }

  @override
  void paint(Canvas canvas, Size size) {
    canvas.drawPath(
      path,
      new Paint()
        ..color = Colors.orange
        ..style = PaintingStyle.stroke
        ..strokeWidth = 4.0,
    );
  }

  @override
  bool shouldRepaint(CustomPainter oldDelegate) {
    return true; // todo - determine if the path has changed
  }
}

GestureDetector is a very extensive Widget in this regard. It has all the capabilities you are searching for. A simpler version of it, which also has Material design built in, is InkWell,但这可能缺少您正在搜索的某些功能。

使用 GestureDetector 包裹您的 Widget,您将能够捕获所有命中事件(您甚至可以指定 HitTestBehavior(使用 behavior 参数)。

对于您的自定义交互,已实现大量回调。我将您链接到 the constructor,其中包含一堆有用的参数,例如 onTapDown/UponVertical/HorizontalDragStart/Update/End.

这还不是全部,但是您可以使用它们以编程方式定义您的行为。让我用一个小例子来解释这个概念:

Offset start;

void verticalDragStart(DragStartDetails details) {
  // process the start by working with the details
  start = details.globalPosition;
  // ...
}

void verticalDragUpdate(DragUpdateDetails details) {
  // apply your logic
  Offset delta = details.delta;
  // ...
}

// use DragEnd, also for horizontal, pan etc.

@override
Widget build(BuildContext context) => GestureDectector(
  onVerticalDragStart: verticalDragStart,
  // ...
);

我希望你能想象这个 启用 的所有可能性。您还可以组合不同的回调。看看 parameters in the documentation 并尝试适合您的内容。

我认为这是您要求的原始数据