Flutter基礎(八)手勢相關Widget:GestureDetector和Dismissible

本文首發於公衆號「劉望舒」前端

ReactNative入門系列 React Native組件 Flutter基礎系列java

前言

移動開發中,用戶交互是一個重要的環節,在Android中的觸摸、點擊、滑動等事件處理都提供了相關的Api,在Flutter中也是同樣的,是由Widget來實現的。 Flutter中的手勢系統有兩個獨立的層。第一層是原始指針事件(pointer events),它描述了屏幕上指針,好比觸摸、鼠標、觸控筆的位置和移動。 第二層是手勢,由一個或多個指針移動組成的動做會被識別爲不一樣的手勢。程序員

1.指針事件

指針表示用戶與設備屏幕交互的原始數據。有四種類型的指針事件:app

  • PointerDownEvent:指針接觸到屏幕的特定位置。
  • PointerMoveEvent: 指針已從屏幕上的一個位置移動到另外一個位置。
  • PointerUpEvent: 指針已中止接觸屏幕。
  • PointerCancelEvent:此指針的輸入再也不指向此應用,通俗來說就是事件取消。

在指針按下時,Flutter框架會對當前應用程序執行命中測試,以肯定指針與屏幕接觸的位置存在哪一個Widget上,而後將PointerDownEvent事件(以及該指針的後續事件)調度到命中測試找到的最內部的Widget,事件的分配路徑爲:從最裏面的Widget到樹的根路徑上的全部Widget。框架

2.手勢

手勢表示由一個或多個指針移動組成的動做。主要有如下幾種:less

點擊ide

onTapDown:指針已經在特定位置與屏幕接觸。 onTapUp:指針中止在特定位置與屏幕接觸。 onTap :點擊事件觸發。 onTapCancel: 先前指針觸發的onTapDown不會再觸發點擊事件。測試

雙擊動畫

onDoubleTap:用戶快速連續兩次在同一位置輕敲屏幕。ui

長按

onLongPress:指針在相同位置長時間保持與屏幕接觸。

垂直拖動

onVerticalDragStart:指針已經與屏幕接觸並可能開始垂直移動。 onVerticalDragUpdate 指針與屏幕接觸並已沿垂直方向移動。 onVerticalDragEnd 先前與屏幕接觸並垂直移動的指針再也不與屏幕接觸,而且在中止接觸屏幕時以特定速度移動。

水平拖動

onHorizontalDragStart:指針已經接觸到屏幕並可能開始水平移動 onHorizontalDragUpdate:指針與屏幕接觸並已沿水平方向移動 onHorizontalDragEnd:先前與屏幕接觸並水平移動的指針再也不與屏幕接觸,並在中止接觸屏幕時以特定速度移動。

如何對這些手勢進行檢測呢?可使用GestureDetector。

3.使用GestureDetector

要想檢測單擊、雙擊、垂直拖動等手勢,只要用GestureDetector嵌套要檢測手勢Widget並實現想要監聽的手勢的方法就行。

import 'package:flutter/material.dart';

void main() => runApp(GestureDetectorWidget());

class GestureDetectorWidget extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: "Flutter",
      home: Scaffold(
        appBar: AppBar(
          title: Text("GestureDetector示例"),
        ),
        body: Center(
          child: GestureDetector(
            child: Text('手勢識別'),
            onTap: () {
              print('點擊');
            },
            onDoubleTap: () {
              print('雙擊');
            },
            onLongPress: () {
              print('長按');
            },
            onHorizontalDragStart: (DragStartDetails details) {
              print('水平拖動');
            },
          ),
        ),
      ),
    );
  }
}
複製代碼

只須要在手勢識別這個文字上進行操做,那麼對應的手勢就會被打印出來。

V5ddxA.png

4.使用Dismissible

滑動刪除這個操做很常見,好比在一個列表中,咱們向左滑動,就會直接刪除一個條目或者給出刪除提示選項。Flutter提供了Dismissible來幫助咱們實現滑動刪除。

import 'package:flutter/material.dart';

void main() => runApp(DismissibleWidget(
      items: new List<String>.generate(300, (i) => "第$i行"),
    ));

class DismissibleWidget extends StatelessWidget {
  final List<String> items;

  DismissibleWidget({@required this.items});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter',
      home: Scaffold(
        appBar: AppBar(
          title: Text('Dismissible示例'),
        ),
        body: ListView.builder(
          itemCount: items.length,
          itemBuilder: (context, index) {
            final item = items[index];
            return Dismissible(
              key: Key(item),
              onDismissed: (direction) {
                items.removeAt(index);
                print(index);
              },
              child: ListTile(
                leading: Icon(Icons.access_time),
                title: Text('${items[index]}'),
              ),
            );
          },
        ),
      ),
    );
  }
}

複製代碼

這個例子和ListView的例子相似,主要的變化就是用Dismissible來嵌套ListTile。當執行刪除操做時,ListView中的onDismissed方法會被回調,咱們能夠直接在onDismissed方法中將被刪除的item從List中移除。

V5dBrt.png

咱們向左滑動第一個和第二個item,會出現刪除的動畫,結果以下圖所示。

V5wpdK.png


這裏不只分享大前端、Android、Java等技術,還有程序員成長類文章。
相關文章
相關標籤/搜索