# Flutter GestureDetector/InkWell/Dismissible 介紹 ## GestureDetector 為元件添加手勢,例如: * 點擊:onTapDown、onTapUp、onTap、onTapCancel * 雙擊:onDoubleTap * 長按:onLongPress * 拖動[垂直/水平]:on[Verticalon/Horizontal]DragStart、on[Verticalon/Horizontal]DragUpdate、on[Verticalon/Horizontal]DragEnd、 * 滑動:onPanStart、onPanUpdate、onPanEnd ### 屬性 #### behavior * HitTestBehavior.deferToChild: 將觸控事件向下傳遞給小元件樹 * HitTestBehavior.opaque: 不會向下傳遞接收觸控事件給小元件樹 * HitTestBehavior.translucent: 允許後臺的小部件接收觸控事件 參考: 1. https://flutter.dev/docs/development/ui/advanced/gestures 2. https://segmentfault.com/a/1190000040706660 ## InkWell 為元件添加水波紋效果(如圖) ![](https://i.imgur.com/q7Bwitn.png) ### 範例程式碼 ```dart InkWell( child: GroceryTile( key: Key(item.id), item: item, onComplete: (change) { manager.completeItem(index, change!); }), onTap: () { Navigator.push( context, MaterialPageRoute( builder: (context) => GroceryItemScreen( originalItem: item, onUpdate: (item) { manager.updateItem(item, index); Navigator.pop(context); }, onCreate: (_) {}, ), ), ); }, ) ``` ### 例外狀況也可以使用Ink 有些時候,使用 Image 或為 Container 設置顏色之後,水波紋就會無法觸發,可改採Ink。 ```dart Widget buildContent() { return Ink( width: 200, height: 0.618 * 200, decoration: const BoxDecoration( image: DecorationImage( fit: BoxFit.cover, image: AssetImage('assets/images/anim_draw.webp'))), child: Padding( padding: const EdgeInsets.all(20), child: Text("Card: 卡片", style: TextStyle(fontSize: 20,color: Colors.white)), )); } ``` ## Dismissible 當用戶向左或向右滑動(或垂直滑動)時從列表中清除項目的小部件(如圖) ![](https://i.imgur.com/tG7263z.png) ### 屬性 * `key` 每个Dismissible實例都必須包含一個Key。Key讓Flutter能夠對Widgets做唯一標示。 * `direction` 甚麼樣的滑動方向觸發`onDismissed` ```dart enum DismissDirection { vertical, horizontal, endToStart, startToEnd, up, down, none } ``` * `onDismissed` 判斷所設定的`direction`是否符合,若符合被移除項目須做甚麼事情。 * `background` 滑動時跑出來的背景色(左滑) * `secondaryBackground` 滑動時跑出來的背景色(右滑),若未設定則使用`background`的顏色 * `resizeDuration` 滑動消失時,下方項目會有一個**上移**的動畫,該動畫時間長度 * `onResize ` 會在動畫執行的每幀中進行callback。 * `dismissThresholds` 表示滑動超過特定百分比觸發`onDismissed`,預設0.4 * `movementDuration` 水平移動至消失的動畫時間 ### 範例程式碼 ```dart Dismissible( key: Key(item.id), direction: DismissDirection.endToStart, background: Container( color: Colors.red, alignment: Alignment.centerRight, child: const Icon(Icons.delete_forever, color: Colors.white, size: 50.0)), onDismissed: (direction) { manager.deleteItem(index); ScaffoldMessenger.of(context).showSnackBar( SnackBar(content: Text('${item.name} dismissed'))); } ``` ###### tags: `flutter`