Flutter learning notes (33) -- GestureDetector gesture recognition

For reprint, please indicate the source: Flutter learning notes (33) -- GestureDetector gesture recognition

The main learning content recorded in this essay is GestureDetector gesture recognition, including recognition of click, double-click, long press, component drag and zoom processing.

  • Click, double-click, long press

First look at the 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, onTap click, onDoubleTap double click and onLongPress long press are callback methods.

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

import 'package:flutter/material.dart';

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

class _GestureDetectorDemo extends State {
  String _operation = "No Gesture detected!"; //Save 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 callback
          onLongPress: () => setState(() => _operation = 'onLongPress'),//Long press callback
        ),
      ),
    );
  }
}

Note: it should be noted here that if the two events onTap and onDoubleTap are monitored at the same time, onTap will have a delay of 200ms, because users are likely to click again to trigger the event of double click after clicking once, so GestureDetector will wait a while to determine whether users want to double-click. If only onTap is monitored but not onDoubleTap Then there will be no delay.

  • Component drag

It's the same as before

import 'package:flutter/material.dart';

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

class _GestureDragDemoState extends State<GestureDragDemo> {
  double _top = 0.0; //Offset from top
  double _left = 0.0; //Offset from 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: <Widget>[
              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 executed when the finger is pressed
//                    print('Where fingers are pressed: $downDetails.globalPosition');
                  },
                  onPanUpdate: (DragUpdateDetails dragUpdateDetails) {
                    //The callback will be executed when the fingers slide
                    setState(() {
                      //Trigger multiple times when fingers slide onPanUpdate Callback, update offset and redraw
                      //dragUpdateDetails.delta.dx obtain y Offset in axis direction
                      _top += dragUpdateDetails.delta.dy;
                      //dragUpdateDetails.delta.dy obtain x Offset in axis direction
                      _left += dragUpdateDetails.delta.dx;
                    });
                  },
                  onPanEnd: (DragEndDetails dragEndDetails) {
                    //At the end of the print slide x,y Speed on axis
//                    print(dragEndDetails.velocity);
                  },
                ),
              ),
            ],
          )),
    );
  }
}
  • DragDownDetails.globalPosition : when the user presses, this property is the offset of the user's pressed position relative to the origin (upper left corner) of the screen (not the parent component).
  • DragUpdateDetails.delta : when the user swims on the screen, multiple Update events will be triggered. Delta refers to the offset of one Update event's slide.
  • DragEndDetails.velocity : this attribute represents the sliding speed (including x and y axes) when the user raises the finger. The example does not deal with the speed when the finger is raised. The common effect is to make a deceleration animation according to the speed when the user raises the finger.

It's also very simple. We mainly lo ok at the callback method onPanUpdate. In the process of finger sliding, this callback will be executed many times. In the callback, we can handle the offset in x and y directions and then draw again.

Offset printing:

  • Single drag

The above drag can be dragged in any direction. In daily development, you may encounter drag only in the horizontal (Jigsaw verification) or vertical direction. The destredetector also provides us with corresponding response events:

Look at the demo example:

import 'package:flutter/material.dart';

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

class _GestureDragDemoState extends State<GestureDragDemo> {
  double _top = 0.0; //Offset from top
  double _left = 0.0; //Offset from 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: <Widget>[
              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 executed when the finger is pressed
//                    print('Where fingers are pressed: $downDetails.globalPosition');
                  },
//                  onPanUpdate: (DragUpdateDetails dragUpdateDetails) {
//                    //The callback will be executed when the fingers slide
//                    setState(() {
//                      //Trigger multiple times when fingers slide onPanUpdate Callback, update offset and redraw
//                      //dragUpdateDetails.delta.dx obtain y Offset in axis direction
//                      _top += dragUpdateDetails.delta.dy;
//                      print('Y: $dragUpdateDetails.delta.dy');
//                      //dragUpdateDetails.delta.dy obtain x Offset in axis direction
//                      _left += dragUpdateDetails.delta.dx;
//                      print('X: $dragUpdateDetails.delta.dx');
//                    });
//                  },
                onHorizontalDragUpdate: (DragUpdateDetails dragUpdateDetails){
                    setState(() {
                      _left += dragUpdateDetails.delta.dx;
                    });
                },
                  onPanEnd: (DragEndDetails dragEndDetails) {
                    //At the end of the print slide x,y Speed on axis
//                    print(dragEndDetails.velocity);
                  },
                ),
              ),
            ],
          )),
    );
  }
}

 

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

class GestureScaleDemo extends StatefulWidget{
  @override
  State<StatefulWidget> 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(() {
                //Zoom multiple at 0.8 Between 10 times
                _width=200*scaleUpdateDetails.scale.clamp(.8, 10.0);
              });
            },
          ),
        ),
      ),
    );
  }
}

Tags: Android Attribute

Posted on Thu, 18 Jun 2020 06:01:13 -0400 by ScoTi