Cử chỉ(Gestures) là một tính năng thú vị trong Flutter cho phép chúng ta tương tác với ứng dụng di động (hoặc bất kỳ thiết bị dựa trên cảm ứng). Nói chung, cử chỉ xác định bất kỳ hành động hoặc chuyển động vật lý nào của người dùng nhằm mục đích kiểm soát thiết bị di động. Một số ví dụ về cử chỉ là:

  • Khi màn hình di động bị khóa, bạn trượt ngón tay trên màn hình để mở khóa.
  • Nhấn vào một nút trên màn hình điện thoại di động của bạn và
  • Nhấn và giữ biểu tượng ứng dụng trên thiết bị dựa trên cảm ứng để kéo biểu tượng đó qua các màn hình.

Chúng ta sử dụng tất cả những cử chỉ này trong cuộc sống hàng ngày để tương tác với điện thoại hoặc thiết bị dựa trên cảm ứng của bạn.

Flutter chia hệ thống cử chỉ thành hai lớp khác nhau, được đưa ra dưới đây:

  1. Con trỏ(Pointers)
  2. Cử chỉ(Gestures)

1. Con trỏ

Con trỏ(Pointers) là lớp đầu tiên đại diện cho dữ liệu thô về tương tác của người dùng. Nó có các sự kiện, mô tả vị tríchuyển động của các con trỏ như chạm, chuột và kiểu trên màn hình. Flutter không cung cấp bất kỳ cơ chế nào để hủy hoặc dừng các sự kiện con trỏ được gửi đi thêm. Flutter cung cấp một widget Listener để lắng nghe các sự kiện con trỏ trực tiếp từ lớp widget. Con trỏ-sự kiện được phân loại thành bốn loại chủ yếu:

  • PointerDownEvents
  • PointerMoveEvents
  • PointerUpEvents
  • PointerCancelEvents

PointerDownEvents: Nó cho phép con trỏ tiếp xúc với màn hình tại một vị trí cụ thể.

PointerMoveEvents: Nó cho phép con trỏ di chuyển từ vị trí này đến vị trí khác trên màn hình.

PointerUpEvents: Nó cho phép con trỏ dừng tiếp xúc với màn hình.

PointerCancelEvents: Sự kiện này được gửi khi tương tác với con trỏ bị hủy.

2. Cử chỉ

Đây là lớp thứ hai đại diện cho các hành động ngữ nghĩa như chạm, kéo và chia tỷ lệ, được nhận dạng từ nhiều sự kiện con trỏ riêng lẻ. Nó cũng có thể gửi nhiều sự kiện tương ứng với vòng đời cử chỉ như kéo bắt đầu, kéo cập nhật và kéo kết thúc. Một số cử chỉ được sử dụng phổ biến được liệt kê dưới đây:

Chạm(Tap): Có nghĩa là chạm vào bề mặt màn hình từ đầu ngón tay trong một thời gian ngắn rồi thả chúng ra. Cử chỉ này chứa các sự kiện sau:

  • onTapDown
  • onTapUp
  • onTap
  • onTapCancel

Nhấn đúp(Double Tap): Nó tương tự như cử chỉ Nhấn, nhưng bạn cần nhấn hai lần trong thời gian ngắn. Cử chỉ này chứa các sự kiện sau:

  • onDoubleTap

Kéo(Drag): Nó cho phép chúng ta chạm vào bề mặt của màn hình bằng đầu ngón tay và di chuyển nó từ vị trí này sang vị trí khác rồi thả chúng ra. Flutter phân loại kéo thành hai loại:

  1. Kéo ngang: Cử chỉ này cho phép con trỏ di chuyển theo hướng ngang. Nó chứa các sự kiện sau:
    • onHorizontalDragStart
    • onHorizontalDragUpdate
    • onHorizontalDragEnd
  2. Kéo dọc: Cử chỉ này cho phép con trỏ di chuyển theo hướng thẳng đứng. Nó chứa các sự kiện sau:
    • onVerticalDragStart
    • onVerticalDragStart
    • onVerticalDragStart

Nhấn lâu(Long Press): Có nghĩa là chạm vào bề mặt của màn hình tại một vị trí cụ thể trong một thời gian dài. Cử chỉ này chứa các sự kiện sau:

  • onLongPress

Di chuyển(Pan) : Có nghĩa là chạm vào bề mặt của màn hình bằng đầu ngón tay, có thể di chuyển theo bất kỳ hướng nào mà không cần nhả đầu ngón tay. Cử chỉ này chứa các sự kiện sau:

  • onPanStart
  • onPanUpdate
  • onPanEnd

Chụm(Pinch): Có nghĩa là chụm (di chuyển ngón tay và ngón cái của một người hoặc đưa chúng lại gần nhau trên màn hình cảm ứng) bề mặt của màn hình bằng cách sử dụng hai ngón tay để phóng to hoặc thu nhỏ màn hình.

3. Dò cử chỉ

Flutter cung cấp một tiện ích hỗ trợ tuyệt vời cho tất cả các loại cử chỉ bằng cách sử dụng tiện ích GestureDetector . GestureWidget là các widget không trực quan, chủ yếu được sử dụng để phát hiện cử chỉ của người dùng. Ý tưởng cơ bản của bộ phát hiện cử chỉ là một tiện ích không trạng thái có chứa các tham số trong hàm tạo của nó cho các sự kiện chạm khác nhau.

Trong một số tình huống, có thể có nhiều bộ phát hiện cử chỉ tại một vị trí cụ thể trên màn hình và sau đó, khung sẽ xác định cử chỉ nào sẽ được gọi. Widget GestureDetector quyết định cử chỉ nào sẽ nhận ra dựa trên lệnh gọi lại nào của nó là không rỗng.

Hãy để chúng ta tìm hiểu cách chúng ta có thể sử dụng các cử chỉ này trong ứng dụng của mình với sự kiện onTap() đơn giản và xác định cách GestureDetector xử lý điều này. Ở đây, chúng ta sẽ tạo một tiện ích hộp, thiết kế nó theo đặc điểm kỹ thuật mong muốn của chúng ta và sau đó thêm hàm onTap() vào nó.

Bây giờ, hãy tạo một dự án Flutter mới và thay thế mã sau trong tệp main.dart .

import 'package:flutter/material.dart';  
  
void main() => runApp(MyApp());  
  
class MyApp extends StatelessWidget {  
  // This widget is the root of your application.  
  @override  
  Widget build(BuildContext context) {  
    return MaterialApp(  
      title: 'Flutter Demo Application', theme: ThemeData(  
      primarySwatch: Colors.green,),  
      home: MyHomePage(),  
    );  
  }  
}  
class MyHomePage extends StatefulWidget {  
  @override  
  MyHomePageState createState() => new MyHomePageState();  
}  
  
class MyHomePageState extends State<MyHomePage> {  
  @override  
  Widget build(BuildContext context) {  
    return new Scaffold(  
      appBar: new AppBar(  
        title: new Text('Gestures Example'),  
        centerTitle: true,  
      ),  
      body: new Center(child: GestureDetector(  
          onTap: () {  
            print('Box Clicked');  
          },  
          child: Container(  
            height: 60.0,  
            width: 120.0,  
            padding: EdgeInsets.all(10.0),  
            decoration: BoxDecoration(  
              color: Colors.blueGrey,  
              borderRadius: BorderRadius.circular(15.0),  
            ),  
            child: Center(child: Text('Click Me')),  
          )  
      )),  
    );  
  }  
}  

Đầu ra

Khi bạn chạy tệp dart này trong Android Studio, nó sẽ đưa ra kết quả sau trong trình giả lập.

Trong hình trên, bạn có thể thấy một nút có các cạnh tròn ở giữa màn hình. Khi bạn nhấn vào nút này, nó hoạt động giống như một nút và có thể thấy đầu ra trong bảng điều khiển.

Flutter cũng cung cấp một tập hợp các widget có thể cho phép bạn thực hiện một cử chỉ cụ thể cũng như nâng cao. Các tiện ích này được đưa ra dưới đây:

Loại bỏ(Dismissible): Đây là một loại widget hỗ trợ cử chỉ vuốt nhẹ để loại bỏ widget.

Draggable: Là một loại widget hỗ trợ cử chỉ kéo để di chuyển widget.

LongPressDraggable: Là một loại widget hỗ trợ cử chỉ kéo để di chuyển widget cùng với widget cha của nó.

DragTarget: Đây là một loại widget có thể chấp nhận bất kỳ widget Draggable nào

DubrePointer: Là một loại widget ẩn widget và các con của nó khỏi quá trình phát hiện cử chỉ.

AbsorbPointer: Đây là một loại widget tự dừng quá trình phát hiện cử chỉ. Do đó, bất kỳ widget chồng chéo nào đều không thể tham gia vào quá trình phát hiện cử chỉ và do đó, không có sự kiện nào được đưa ra.

Scrollable: Đây là một loại widget hỗ trợ cuộn nội dung có sẵn bên trong widget.

4. Ví dụ nhiều cử chỉ

Trong phần này, chúng ta sẽ xem nhiều cử chỉ hoạt động như thế nào trong các ứng dụng rung. Ứng dụng demo này bao gồm hai vùng chứa chính và con. Ở đây, mọi thứ được xử lý thủ công bằng cách sử dụng ‘RawGestureDetector’ và ‘GestureRecognizer’ tùy chỉnh GestureRecognizer tùy chỉnh cung cấp thuộc tính ‘AllowMultipleGestureRecognizer’ vào danh sách cử chỉ và tạo một ‘GestureRecognizerFactoryWithHandlers’. Tiếp theo, khi sự kiện onTap () được gọi, nó sẽ in văn bản ra bảng điều khiển.

Mở dự án flutter và thay thế code sau trong tệp main.dart,

import 'package:flutter/gestures.dart';  
import 'package:flutter/material.dart';  
  
//It is the entry point for your Flutter app.  
void main() {  
  runApp(  
    MaterialApp(  
      title: 'Multiple Gestures Demo',  
      home: Scaffold(  
        appBar: AppBar(  
          title: Text('Multiple Gestures Demo'),  
        ),  
        body: DemoApp(),  
      ),  
    ),  
  );  
}  
  
class DemoApp extends StatelessWidget {  
  @override  
  Widget build(BuildContext context) {  
    return RawGestureDetector(  
      gestures: {  
        AllowMultipleGestureRecognizer: GestureRecognizerFactoryWithHandlers<  
            AllowMultipleGestureRecognizer>(  
              () => AllowMultipleGestureRecognizer(),  
              (AllowMultipleGestureRecognizer instance) {  
            instance.onTap = () => print('It is the parent container gesture');  
          },  
        )  
      },  
      behavior: HitTestBehavior.opaque,  
      //Parent Container  
      child: Container(  
        color: Colors.green,  
        child: Center(  
          //Now, wraps the second container in RawGestureDetector  
          child: RawGestureDetector(  
            gestures: {  
              AllowMultipleGestureRecognizer:  
              GestureRecognizerFactoryWithHandlers<  
                  AllowMultipleGestureRecognizer>(  
                    () => AllowMultipleGestureRecognizer(),  //constructor  
                    (AllowMultipleGestureRecognizer instance) {  //initializer  
                  instance.onTap = () => print('It is the nested container');  
                },  
              )  
            },  
            //Creates the nested container within the first.  
            child: Container(  
              color: Colors.deepOrange,  
              width: 250.0,  
              height: 350.0,  
            ),  
          ),  
        ),  
      ),  
    );  
  }  
}  
  
class AllowMultipleGestureRecognizer extends TapGestureRecognizer {  
  @override  
  void rejectGesture(int pointer) {  
    acceptGesture(pointer);  
  }  
} 

Đầu ra

Khi bạn chạy ứng dụng, nó sẽ đưa ra kết quả sau.

Tiếp theo, chạm vào ô màu cam, kết quả sau xuất hiện trên console của bạn.

It is the nested container.
It is the parent container gesture.

Cài ứng dụng cafedev để dễ dàng cập nhật tin và học lập trình mọi lúc mọi nơi tại đây.

Tài liệu từ cafedev:

Nếu bạn thấy hay và hữu ích, bạn có thể tham gia các kênh sau của cafedev để nhận được nhiều hơn nữa:

Chào thân ái và quyết thắng! 

Đăng ký kênh youtube để ủng hộ Cafedev nha các bạn, Thanks you!