Flutter event monitoring

Flutter event monitoring

1. Event monitoring

In the development of large front-ends, there are bound to be various situations of interaction with users: such as finger click, finger slide, double click, long press, and so on.

All content was first published on the public account: coderwhy

In Flutter, there are two different levels of gestures:

  • The first layer: Pointer Events: describes the position and movement of the pointer triggered by the touchpad, mouse, stylus, etc. on the screen.
  • The second layer: Gesture Detector: This is a kind of encapsulation on the original event.
    • For example, if we want to monitor the user's long press, if we encapsulate the original event by ourselves, we need to monitor the time from the user's press to the lift to determine whether it is a long press event;
    • For example, we need to monitor the user's double-click event, and we need to encapsulate the time interval between the user's two presses and lifts by ourselves;
    • Fortunately, almost all platforms have encapsulated them, and gesture recognition in Flutter is the encapsulation of raw pointer events;
    • What gestures are included? Such as click, double click, long press, drag, etc.

2.1. Pointer event Pointer

Pointer represents the raw data of human-computer interface interaction. There are four pointer events:

What is the principle of Pointer?

  • When the pointer falls, the framework performs a hit test operation to determine which Widgets are in contact with the screen and distribute them to the innermost component to respond;

  • The event will bubble and distribute along the innermost component to the root of the component tree;

  • And there is no mechanism for canceling or stopping the further distribution of pointer events;

The original pointer events use Listener to monitor:

class HomeContent extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Center(
      child: Listener(
        child: Container(
          width: 200,
          height: 200,
          color: Colors.red,
        ),
        onPointerDown: (event) => print(" :$event"),
        onPointerMove: (event) => print(" :$event"),
        onPointerUp: (event) => print(" :$event"),
      ),
    );
  }
}
 
image-20190925154947943

2.2. Gesture recognition

Gesture is a package of a series of Pointers. The official recommendation is to use Gesture instead of Pointer in development as much as possible.

It is recommended to use Gesture

There are many types of Gesture layers:

Click :

  • onTapDown: The user's finger press operation
  • onTapUp: the user's finger lift operation
  • onTap: The user click event is complete
  • onTapCancel: The event is canceled during the press

Double click:

  • onDoubleTap: Tap twice quickly

Press:

  • onLongPress: keeps on the screen for a while

Drag vertically:

  • onVerticalDragStart: The pointer makes contact with the screen and may start to move vertically;
  • onVerticalDragUpdate: The pointer is in contact with the screen, and it moves vertically and keeps moving;
  • onVerticalDragEnd: the end of the contact between the pointer and the screen;

Horizontal dragging:

  • onHorizontalDragStart: The pointer makes contact with the screen and may start to move horizontally;
  • onHorizontalDragUpdate: The pointer makes contact with the screen, moves in the horizontal direction and keeps moving;
  • onHorizontalDragEnd: the end of the contact between the pointer and the screen;

mobile:

  • onPanStart: The pointer makes contact with the screen and may start moving horizontally or vertically. If you set onHorizontalDragStartor onVerticalDragStart, the callback method will lead to collapse;
  • onPanUpdate: The pointer is in contact with the screen, and it moves horizontally or vertically and keeps moving. If you set onHorizontalDragUpdateor onVerticalDragUpdate, the callback method will lead to a crash.
  • onPanEnd: The pointer has previously made contact with the screen and moved at a certain speed, and then no longer moves on the screen contact. If you set onHorizontalDragEndor onVerticalDragEnd, the callback method will lead to a crash.

To monitor gestures from the Widget level, we need to use: GestureDetector

  • Of course, we can also use RaisedButton, FlatButton, InkWell, etc. to monitor gestures
  • globalPosition is used to obtain position information relative to the screen
  • localPosition is used to obtain position information relative to the current Widget
class HYHomePage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(" "),
      ),
      body: GestureDetector(
        child: Container(
          width: 200,
          height: 200,
          color: Colors.red,
        ),
        onTap: () {

        },
        onTapDown: (detail) {
          print(detail.globalPosition);
          print(detail.localPosition);
        },
        onTapUp: (detail) {
          print(detail.globalPosition);
          print(detail.localPosition);
        }
      ),
    );
  }
}

 
image-20200317172326395

2. Cross-component events

If there is an event that needs to be passed between components, on the one hand, it can be passed layer by layer, on the other hand, we can also use an EventBus tool to complete.

In fact, EventBus is a very common way of cross-component communication in Vue and React:

  • EventBus is equivalent to a subscriber model, managed through a global object;
  • We can implement this EventBus ourselves, or use a third-party EventBus;

Here we directly choose the third-party EventBus:

dependencies:
  event_bus: ^1.1.1
 

First: We need to define an object that we want to pass between components:

  • We can call it a time object, or it can be a model object (model) we usually use in development
class UserInfo {
  String nickname;
  int level;
  
  UserInfo(this.nickname, this.level);
}
 

Second: Create a global EventBus object

final eventBus = EventBus();
 

Third: In a Widget, issue an event:

class HYButton extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return RaisedButton(
      child: Text("HYButton"),
      onPressed: () {
        final info = UserInfo("why", 18);
        eventBus.fire(info);
      },
    );
  }
}
 

Fourth: In a Widget, listen for events

class HYText extends StatefulWidget {
  @override
  _HYTextState createState() => _HYTextState();
}

class _HYTextState extends State<HYText> {
  String message = "Hello Coderwhy";

  @override
  void initState() {
    super.initState();

    eventBus.on<UserInfo>().listen((data) {
      setState(() {
        message = "${data.nickname}-${data.level}";
      });
    });
  }

  @override
  Widget build(BuildContext context) {
    return Text(message, style: TextStyle(fontSize: 30),);
  }
}
 

Remarks: All content is first published on the official account. After that, in addition to Flutter, other technical articles will be updated, such as TypeScript, React, Node, uniapp, mpvue, data structure and algorithms, etc., and some of their own learning experience will also be updated. Welcome everyone to pay attention

the public