Notes on flutter (33) — gesture recognition of gesturedetector

Time:2020-12-25

If you need to reprint, please indicate the source:Notes on flutter (33) — gesture recognition of gesturedetector

This essay mainly records the learning content of gesturedetector gesture recognition, including recognition of click, double-click, long press, component drag and zoom processing.

  • Click, double-click and long press

Let’s take a look at demo. It’s very simple. Gesturedetector itself is also a component. Gesturedetector recognizes the gesture actions of its internal sub components. In the construction method of gesturedetector, we provide OnTap click, ondoubletap double-click and onlongpress long-press callback methods.

After recognizing the user‘s gesture operation, the corresponding callback method will be executed. The processing of demo is simply to update the text copy.

import 'package:flutter/material.dart';

class GestureDetectorDemo extends StatefulWidget {
  @override
  State createState() {
    return _GestureDetectorDemo();
  }
}

class _GestureDetectorDemo extends State {
  String _ Operation = "no gesture detected!"; // save the event name
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'GestureDetectorDemo',
      home: new Scaffold(
        appBar: AppBar(
          title: Text('GestureDetectorDemo'),
          leading: Icon(Icons.arrow_back),
        ),
        body: new GestureDetector(
          child: Container(
            alignment: Alignment.center,
            color: Colors.red,
            width: 300,
            height: 200,
            child: Text(
              _operation,
              style: TextStyle(color: Colors.teal),
            ),
          ),
          onTap: () => setState(() => _ Operation: 'OnTap'), // single machine callback
          onDoubleTap: () => setState(() => _ Operation ='ondoubletap ') // double click the callback
          onLongPress: () => setState(() => _ Operation ='onlongpress'), // long press callback
        ),
      ),
    );
  }
}

Note: to explain here, if OnTap and ondoubletap are monitored at the same time, OnTap will have a delay of 200ms, because the user is likely to click again after one click to trigger the double-click event. Therefore, gesturedetector will wait for a period of time to determine whether the user wants to double-click or not. If the user only listensIf OnTap is not monitored on doubletap, there will be no delay.

  • Component drag

As usual, watch the demo first and then explain:

import 'package:flutter/material.dart';

class GestureDragDemo extends StatefulWidget {
  @override
  State createState() {
    return _GestureDragDemoState();
  }
}

class _GestureDragDemoState extends State {
  double _ Top = 0.0; // offset from top
  double _ Left = 0.0; // offset from the bottom
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'GestureDragDemo',
      home: Scaffold(
          appBar: AppBar(
            title: Text('GestureDragDemo'),
            leading: Icon(Icons.keyboard_backspace),
          ),
          body: Stack(
            children: [
              Positioned(
                top: _top,
                left: _left,
                child: GestureDetector(
                  child: CircleAvatar(
                    backgroundColor: Colors.red,
                    child: Text(
                      'A',
                      style: TextStyle(color: Colors.white),
                    ),
                  ),
                  onPanDown: (DragDownDetails downDetails) {
                    //This callback is performed when the finger is pressed
//Print ('finger pressed position:$ downDetails.globalPosition ).
                  },
                  onPanUpdate: (DragUpdateDetails dragUpdateDetails) {
                    //The second callback is performed when the finger swipes
                    setState(() {
                      //The onpanupdate callback is triggered multiple times as the finger swipes, updating the offset and redrawing
                      // dragUpdateDetails.delta.dx Gets the offset in the y-axis direction
                      _top += dragUpdateDetails.delta.dy;
                      // dragUpdateDetails.delta.dy Gets the offset in the x-axis direction
                      _left += dragUpdateDetails.delta.dx;
                    });
                  },
                  onPanEnd: (DragEndDetails dragEndDetails) {
                    //Print the speed on the X and Y axes at the end of the slide
//                    print(dragEndDetails.velocity);
                  },
                ),
              ),
            ],
          )),
    );
  }
}
  • DragDownDetails.globalPosition: when the user presses, this attribute is the position of the user’s press relative to thescreenThe offset of the origin (upper left corner) of (not the parent component).
  • DragUpdateDetails.delta: multiple update events are triggered when the user swipes on the screen,deltaRefers to the offset of the sliding of an update event.
  • DragEndDetails.velocity: this attribute represents the sliding speed of the user when lifting the finger (including the X and Y axes). In the example, the speed of the finger is not handled. The common effect is to make a deceleration animation according to the speed of the user lifting the finger.

It’s also very simple. We’ll mainly look at the onpanupdate callback method. In the process of sliding our fingers, we will execute this callback many times. In the callback, we will process the offsets in the X and Y directions and then redraw them.

Offset printing:

  •  Single direction drag

The drag above can be dragged in any direction. In daily development, it is possible to drag only horizontally (puzzle verification) or vertically. Desturedetector also provides us with corresponding response events

Take a look at a demo example:

import 'package:flutter/material.dart';

class GestureDragDemo extends StatefulWidget {
  @override
  State createState() {
    return _GestureDragDemoState();
  }
}

class _GestureDragDemoState extends State {
  double _ Top = 0.0; // offset from top
  double _ Left = 0.0; // offset from the bottom
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'GestureDragDemo',
      home: Scaffold(
          appBar: AppBar(
            title: Text('GestureDragDemo'),
            leading: Icon(Icons.keyboard_backspace),
          ),
          body: Stack(
            children: [
              Positioned(
                top: _top,
                left: _left,
                child: GestureDetector(
                  child: CircleAvatar(
                    backgroundColor: Colors.red,
                    child: Text(
                      'A',
                      style: TextStyle(color: Colors.white),
                    ),
                  ),
                  onPanDown: (DragDownDetails downDetails) {
                    //This callback is performed when the finger is pressed
//Print ('finger pressed position:$ downDetails.globalPosition ).
                  },
//                  onPanUpdate: (DragUpdateDetails dragUpdateDetails) {
//// the callback is executed when the finger is sliding
//                    setState(() {
//// the onpanupdate callback is triggered multiple times when the finger swipes, updating the offset and redrawing
//                      // dragUpdateDetails.delta.dx Gets the offset in the y-axis direction
//                      _top += dragUpdateDetails.delta.dy;
//                      print('Y:$dragUpdateDetails.delta.dy');
//                      // dragUpdateDetails.delta.dy Gets the offset in the x-axis direction
//                      _left += dragUpdateDetails.delta.dx;
//                      print('X:$dragUpdateDetails.delta.dx');
//                    });
//                  },
                onHorizontalDragUpdate: (DragUpdateDetails dragUpdateDetails){
                    setState(() {
                      _left += dragUpdateDetails.delta.dx;
                    });
                },
                  onPanEnd: (DragEndDetails dragEndDetails) {
                    //Print the speed on the X and Y axes at the end of the slide
//                    print(dragEndDetails.velocity);
                  },
                ),
              ),
            ],
          )),
    );
  }
}

 

  •  zoom
import 'package:flutter/material.dart';

class GestureScaleDemo extends StatefulWidget{
  @override
  State createState() {
    return _GestureScaleDemoState();
  }
}

class _GestureScaleDemoState extends State {
  double _width = 200.0;
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'GestureScaleDemo',
      home: Scaffold(
        appBar: AppBar(
          title: Text('GestureScaleDemo'),
        ),
        body: Center(
          child: GestureDetector(
            child: Image.asset('images/banner.png',width: _width),
            onScaleUpdate: (ScaleUpdateDetails scaleUpdateDetails){
              setState(() {
                //The zoom factor is between 0.8 and 10 times
                _width=200*scaleUpdateDetails.scale.clamp(.8, 10.0);
              });
            },
          ),
        ),
      ),
    );
  }
}