[譯]Flutter for Android Developers – Gesture Detection

catsuo發表於2019-03-04

在Flutter中怎樣為一個Widget新增點選事件監聽器

  • in Android

    • 我們通常呼叫一個View的setOnClickListener方法來監聽一個View的點選事件。
  • in Flutter

    • 我們視情況不同有兩種實現方法,一是直接傳遞一個處理事件的方法給Widget,二是通過GestureDetector來實現事件監聽與處理。

下面兩個例子對兩種實現方法做簡要說明:

@override
Widget build(BuildContext context) {
  return new RaisedButton(
      onPressed: () {
        print("click");
      },
      child: new Text("Button"));
}
複製程式碼

這個例子描述瞭如何使用第一種方法實現點選事件監聽。其實很簡單,在構造RaisedButton時直接傳遞一個用於處理事件的方法給onPressed引數就可以了,當RaisedButton被點選時名為onPressed的引數所指向的方法就會被呼叫。在這裡就是簡單的列印出”click”。

Note:
這種方法僅當Widget本身已經支援事件監聽時使用。比如這裡的RaisedButton是系統提供的一個Widget,其本身已經支援了事件監聽,所以可以直接在構造時傳遞一個用於處理事件的方法給它。

class SampleApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return new Scaffold(
        body: new Center(
      child: new GestureDetector(
        child: new FlutterLogo(
          size: 200.0,
        ),
        onTap: () {
          print("tap");
        },
      ),
    ));
  }
}
複製程式碼

這個例子描述瞭如何使用第二種方法實現點選事件監聽。這裡的關鍵是GestureDetector,我們將需要響應點選事件的Widget包裹到GestureDetector內部,並且傳遞一個用來處理點選事件的方法給GestureDetector的onTap引數,當點選事件發生時onTap所指向的方法就會被呼叫。在這裡就是簡單的列印出”tap”。

Note:
這種方法在Widget本身不支援事件監聽時使用。

小結:
在Flutter中實現點選事件的監聽處理有兩種方法。
針對本身支援事件監聽的Widget可以直接在構造Widget時傳入一個方法用於點選事件處理。
針對本身不支援事件監聽的Widget可以將其包裹在一個GestureDetector內部來實現點選事件處理。

在Flutter中怎樣處理其他事件

  • in Android

    1. 我們可以通過各個元件提供的介面來設定相應的事件監聽器來監聽並處理我們所關心的事件。
    2. 直接監聽touch事件自行判定事件的型別並處理事件。
    3. 通過GestureDetector類來幫助監聽各種手勢事件。
  • in Flutter

    • 也有一個GestureDetector類存在,利用它我們可以監聽很多事件。

在Flutter中GestureDetector可以監聽以下事件:

  • Tap

    • onTapDown 監聽處理一個剛剛接觸到螢幕的事件,類似於Android中Action為ACTION_DOWN的touch event。
    • onTapUp 監聽處理一個接觸螢幕後的離屏事件,類似於Android中Action為ACTION_UP的touch event。
    • onTap 監聽處理一個點選事件,類似於Android中的onClick。
    • onTapCancel 類似Android中Action為ACTION_CANCEL的touch event。出現該事件的原因可能是從ACTION_DOWN到ACTION_UP的過程當中因為手指移出可互動區或者其他異常導致的。
  • Double tap

    • onDoubleTap 監聽處理一個雙擊事件。
  • Long press

    • onLongPress 監聽處理一個長按事件。
  • Vertical drag

    • onVerticalDragStart 監聽處理一個垂直方向拖拽事件的開始。
    • onVerticalDragUpdate 監聽處理一個垂直方向拖拽事件在拖拽過程中的移動。
    • onVerticalDragEnd 監聽處理一個垂直方向拖拽事件的結束。
  • Horizontal drag

    • onHorizontalDragStart 監聽處理一個水平方向拖拽事件的開始。
    • onHorizontalDragUpdate 監聽處理一個水平方向的拖拽事件在拖拽過程中的移動。
    • onHorizontalDragEnd 監聽處理一個水平方向的拖拽事件的結束。

下面的例子簡單展示瞭如何使用GestureDetector來監聽一個Double tap事件:

AnimationController controller;
CurvedAnimation curve;

@override
void initState() {
  controller = new AnimationController(duration: const Duration(milliseconds: 2000), vsync: this);
  curve = new CurvedAnimation(parent: controller, curve: Curves.easeIn);
}

class SampleApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return new Scaffold(
        body: new Center(
          child: new GestureDetector(
            child: new RotationTransition(
                turns: curve,
                child: new FlutterLogo(
                  size: 200.0,
                )),
            onDoubleTap: () {
              if (controller.isCompleted) {
                controller.reverse();
              } else {
                controller.forward();
              }
            },
        ),
    ));
  }
}
複製程式碼

在這個例子中我們想讓一個FlutterLogo響應Double tap事件,但是FlutterLogo本身是不支援事件處理的Widget,所以這裡將其包裹在GestureDetector內部,並通過GestureDetector的onDoubleTap引數來傳遞一個用於處理Double tap事件的方法。
因為這個例子是想FlutterLogo在接收到Double tap事件後去執行一個旋轉動畫,所以這裡並不是直接將FlutterLogo包裹在GestureDetector內部,而是先用描述一個旋轉動畫的元件RotationTransition包裹FlutterLogo,接著再在外層用GestureDetector包裹RotationTransition元件。關於在Flutter中實現動畫的介紹可以參閱FFAD-Views

小結:
在Flutter中使用GestureDetector可以監聽處理大多數型別的事件,使用時只要將我們想要接收事件的Widget包裹在GestureDetector內部,並傳遞事件處理方法給相應的引數即可。

英文原版傳送

相關文章