Flutter學習筆記(33)--GestureDetector手勢識別

来源:https://www.cnblogs.com/upwgh/archive/2020/06/18/13157670.html
-Advertisement-
Play Games

這篇隨筆主要記錄的學習內容是GestureDetector手勢識別,內容包括識別單擊、雙擊、長按、組件拖拽和縮放處理。 ...


如需轉載,請註明出處:Flutter學習筆記(33)--GestureDetector手勢識別

這篇隨筆主要記錄的學習內容是GestureDetector手勢識別,內容包括識別單擊、雙擊、長按、組件拖拽和縮放處理。

  • 單擊、雙擊、長按

先看下demo,很簡單,GestureDetector本身也是一個組件,GestureDetector識別其內部子組件的手勢動作,GestureDetector的構造方法內給我們提供了onTap單擊、onDoubleTap雙擊、onLongPress長按的是回調方法。

識別到用戶的手勢操作後會執行對應的回調方法,demo的處理就是簡單的更新一下text的文案。

import 'package:flutter/material.dart';

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

class _GestureDetectorDemo extends State {
  String _operation = "No Gesture detected!"; //保存事件名
  @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'),//單機回調
          onDoubleTap: () => setState(() => _operation = 'onDoubleTap'),//雙擊回調
          onLongPress: () => setState(() => _operation = 'onLongPress'),//長按回調
        ),
      ),
    );
  }
}

註:這裡要說明一下,如果同時監聽的onTap和onDoubleTap這兩個事件的話,onTap會有200ms的延時,因為因為用戶在點擊一次之後很有可能會再點擊一次來觸發雙擊的事件,所以GestureDetector會等一段時間來確定用戶是不是要雙擊,如果只是監聽了onTap而沒有監聽onDoubleTap的話,就不會有延時了。

  • 組件拖動

老樣子先看demo再講解:

import 'package:flutter/material.dart';

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

class _GestureDragDemoState extends State<GestureDragDemo> {
  double _top = 0.0; //距離頂部的偏移量
  double _left = 0.0; //距離底部的偏移量
  @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) {
                    //手指按下時會執行此回調
//                    print('手指按下的位置:$downDetails.globalPosition');
                  },
                  onPanUpdate: (DragUpdateDetails dragUpdateDetails) {
                    //手指滑動時會執行次回調
                    setState(() {
                      //手指滑動時會多次觸發onPanUpdate回調,更新偏移量並重新繪製
                      //dragUpdateDetails.delta.dx獲取y軸方向的偏移量
                      _top += dragUpdateDetails.delta.dy;
                      //dragUpdateDetails.delta.dy獲取x軸方向的偏移量
                      _left += dragUpdateDetails.delta.dx;
                    });
                  },
                  onPanEnd: (DragEndDetails dragEndDetails) {
                    //列印滑動結束時在x、y軸上的速度
//                    print(dragEndDetails.velocity);
                  },
                ),
              ),
            ],
          )),
    );
  }
}
  • DragDownDetails.globalPosition:當用戶按下時,此屬性為用戶按下的位置相對於屏幕(而非父組件)原點(左上角)的偏移。
  • DragUpdateDetails.delta:當用戶在屏幕上滑動時,會觸發多次Update事件,delta指一次Update事件的滑動的偏移量。
  • DragEndDetails.velocity:該屬性代表用戶抬起手指時的滑動速度(包含x、y兩個軸的),示例中並沒有處理手指抬起時的速度,常見的效果是根據用戶抬起手指時的速度做一個減速動畫。

也很簡單,我們主要看下onPanUpdate這個回調方法,在我們手指滑動的過程中,會多次執行這個回調,在回調中我們處理下x、y方向的偏移量讓後重新繪製就ok了。

偏移量列印:

  •  單一方向拖動

上面的拖動是可以往任意方向拖動的,在日常的開發中,有可能會遇到只允許水平(拼圖驗證)或豎直方向上進行拖動,DestureDetector也為我們提供了對應的響應事件:

看下demo示例:

import 'package:flutter/material.dart';

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

class _GestureDragDemoState extends State<GestureDragDemo> {
  double _top = 0.0; //距離頂部的偏移量
  double _left = 0.0; //距離底部的偏移量
  @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) {
                    //手指按下時會執行此回調
//                    print('手指按下的位置:$downDetails.globalPosition');
                  },
//                  onPanUpdate: (DragUpdateDetails dragUpdateDetails) {
//                    //手指滑動時會執行次回調
//                    setState(() {
//                      //手指滑動時會多次觸發onPanUpdate回調,更新偏移量並重新繪製
//                      //dragUpdateDetails.delta.dx獲取y軸方向的偏移量
//                      _top += dragUpdateDetails.delta.dy;
//                      print('Y:$dragUpdateDetails.delta.dy');
//                      //dragUpdateDetails.delta.dy獲取x軸方向的偏移量
//                      _left += dragUpdateDetails.delta.dx;
//                      print('X:$dragUpdateDetails.delta.dx');
//                    });
//                  },
                onHorizontalDragUpdate: (DragUpdateDetails dragUpdateDetails){
                    setState(() {
                      _left += dragUpdateDetails.delta.dx;
                    });
                },
                  onPanEnd: (DragEndDetails dragEndDetails) {
                    //列印滑動結束時在x、y軸上的速度
//                    print(dragEndDetails.velocity);
                  },
                ),
              ),
            ],
          )),
    );
  }
}

 

  •  縮放
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(() {
                //縮放倍數在0.8到10倍之間
                _width=200*scaleUpdateDetails.scale.clamp(.8, 10.0);
              });
            },
          ),
        ),
      ),
    );
  }
}

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • redisObject redis 是 key-value 存儲系統,其中key類型一般為字元串,而 value 類型則為 redis 對象(redisObject)。Redis 對象可以綁定各種類型的數據,譬如 string、list 和set。因此他能很好的將屬性和數據分離開。 typedef ...
  • Redis集群 ·Redis集群提供了一種運行Redis安裝的方法,在該安裝中,數據會在多個Redis節點之間自動分片。 Redis集群在分區期間還提供了一定程度的可用性,這實際上是在某些節點出現故障或無法通信時有繼續工作的能力。但是,如果發生較嚴重故障(例如,大多數主節點不可用時),集群將停止運行 ...
  • 一個事務執行dml操作,就會自動加上行共用表鎖,以防止其他需要排他鎖的事務訪問。 一個事務對錶新增數據,另一個事務修改表報錯顯示“資源正忙...”,因為修改該表時需要排他鎖。 一個事務修改表數據,或刪除表數據,就是真正的影響記錄數為0,另一個事務依然無法修改該表,因為修改該表時需要排他鎖。 ...
  • 先上個pgsql操作的對比,然後引出ignite的並置處理規則 ddl: drop table student;CREATE TABLE student(sid int PRIMARY KEY ,sname varchar(64), cid int); drop table course;CREAT ...
  • 本文章更新於2020-06-14,使用MySQL 5.7,操作系統為Deepin 15.9。 說明:下文中,小寫為自定義變數,根據實際情況填寫(個別小寫的參數除外)。使用[]引起表示內容可選,使用{}引起表示內容為一個整體,|表示使用左側或右側內容,...表示重覆之前內容。 實際上,所有語句和命令的 ...
  • 前置條件 用戶有查詢數據統計許可權 GRANT VIEW DATABASE STATE TO database_user; CPU性能問題 正在發生 查看前X個CPU消耗查詢 (彙總) SELECT TOP 10 GETDATE() runtime, * FROM ( SELECT query_sta ...
  • 在Android我們經常會使用到EventBus來進行通信,常用到的場景就是不同的頁面來傳遞數據,Flutter中也可以通過EventBus來進行不同頁面間的數據傳遞。 EventBus就是一條事件訂閱匯流排,有事件的訂閱者、事件的發佈者。 demo就是模擬了一下頁面間的數據傳遞,頁面A跳轉到頁面... ...
  • 關於演算法的想法 由於面試可能需要手寫演算法,網上搜羅了一些資料,整理了下演算法的OC的實現代碼,雖然平時開發中一般用不到,但是多積累一些技術知識,還是對以後發展大有裨益的 github上搜集的幾大演算法原理和實現代碼,只有JavaScript、Python、Go、Java的實現代碼 演算法文字理解和OC代碼 ...
一周排行
    -Advertisement-
    Play Games
  • C#TMS系統代碼-基礎頁面BaseCity學習 本人純新手,剛進公司跟領導報道,我說我是java全棧,他問我會不會C#,我說大學學過,他說這個TMS系統就給你來管了。外包已經把代碼給我了,這幾天先把增刪改查的代碼背一下,說不定後面就要趕鴨子上架了 Service頁面 //using => impo ...
  • 委托與事件 委托 委托的定義 委托是C#中的一種類型,用於存儲對方法的引用。它允許將方法作為參數傳遞給其他方法,實現回調、事件處理和動態調用等功能。通俗來講,就是委托包含方法的記憶體地址,方法匹配與委托相同的簽名,因此通過使用正確的參數類型來調用方法。 委托的特性 引用方法:委托允許存儲對方法的引用, ...
  • 前言 這幾天閑來沒事看看ABP vNext的文檔和源碼,關於關於依賴註入(屬性註入)這塊兒產生了興趣。 我們都知道。Volo.ABP 依賴註入容器使用了第三方組件Autofac實現的。有三種註入方式,構造函數註入和方法註入和屬性註入。 ABP的屬性註入原則參考如下: 這時候我就開始疑惑了,因為我知道 ...
  • C#TMS系統代碼-業務頁面ShippingNotice學習 學一個業務頁面,ok,領導開完會就被裁掉了,很突然啊,他收拾東西的時候我還以為他要旅游提前請假了,還在尋思為什麼回家連自己買的幾箱飲料都要叫跑腿帶走,怕被偷嗎?還好我在他開會之前拿了兩瓶芬達 感覺感覺前面的BaseCity差不太多,這邊的 ...
  • 概述:在C#中,通過`Expression`類、`AndAlso`和`OrElse`方法可組合兩個`Expression<Func<T, bool>>`,實現多條件動態查詢。通過創建表達式樹,可輕鬆構建複雜的查詢條件。 在C#中,可以使用AndAlso和OrElse方法組合兩個Expression< ...
  • 閑來無聊在我的Biwen.QuickApi中實現一下極簡的事件匯流排,其實代碼還是蠻簡單的,對於初學者可能有些幫助 就貼出來,有什麼不足的地方也歡迎板磚交流~ 首先定義一個事件約定的空介面 public interface IEvent{} 然後定義事件訂閱者介面 public interface I ...
  • 1. 案例 成某三甲醫預約系統, 該項目在2024年初進行上線測試,在正常運行了兩天後,業務系統報錯:The connection pool has been exhausted, either raise MaxPoolSize (currently 800) or Timeout (curren ...
  • 背景 我們有些工具在 Web 版中已經有了很好的實踐,而在 WPF 中重新開發也是一種費時費力的操作,那麼直接集成則是最省事省力的方法了。 思路解釋 為什麼要使用 WPF?莫問為什麼,老 C# 開發的堅持,另外因為 Windows 上已經裝了 Webview2/edge 整體打包比 electron ...
  • EDP是一套集組織架構,許可權框架【功能許可權,操作許可權,數據訪問許可權,WebApi許可權】,自動化日誌,動態Interface,WebApi管理等基礎功能於一體的,基於.net的企業應用開發框架。通過友好的編碼方式實現數據行、列許可權的管控。 ...
  • .Net8.0 Blazor Hybird 桌面端 (WPF/Winform) 實測可以完整運行在 win7sp1/win10/win11. 如果用其他工具打包,還可以運行在mac/linux下, 傳送門BlazorHybrid 發佈為無依賴包方式 安裝 WebView2Runtime 1.57 M ...