網(wǎng)站首頁(yè) 編程語(yǔ)言 正文
簡(jiǎn)介
之前我們介紹了GestureDetector的定義和其提供的一些基本的方法,GestureDetector的好處就是可以把任何一個(gè)widget都賦予類(lèi)似button的功能。
今天將會(huì)通過(guò)幾個(gè)具體的例子來(lái)講解一下GestureDetector的具體使用。
賦予widget可以點(diǎn)擊的功能
一般情況下,我們的普通widget,比如文本是不能進(jìn)行交互的,但是如果將其用GestureDetector進(jìn)行包裝之后,就可以將其偽裝成為一個(gè)button。
比如我們有這樣一個(gè)偽裝成button的Container:
Container(
padding: const EdgeInsets.all(12.0),
decoration: BoxDecoration(
color: Colors.green,
borderRadius: BorderRadius.circular(8.0),
),
child: const Text('My Button'),
)
這個(gè)Container的本質(zhì)是一個(gè)Text,這個(gè)Container本身是沒(méi)有交互功能的,那么如何對(duì)其添加交互功能呢?
最簡(jiǎn)單的辦法就是將其使用GestureDetector包裝起來(lái),如下所示:
GestureDetector(
// The custom button
child: Container(
padding: const EdgeInsets.all(12.0),
decoration: BoxDecoration(
color: Colors.green,
borderRadius: BorderRadius.circular(8.0),
),
child: const Text('My Button'),
),
)
接下來(lái)我們還要為其添加對(duì)應(yīng)的手勢(shì),這里我們添加一個(gè)onTap方法,
GestureDetector(
onTap: ()=> showDialog<String>(
context: context,
builder: (BuildContext context) => AlertDialog(
title: const Text('基本手勢(shì)'),
content: const Text('這是基本的手勢(shì),你學(xué)會(huì)了嗎?'),
actions: <Widget>[
TextButton(
onPressed: () => Navigator.pop(context, 'Cancel'),
child: const Text('Cancel'),
),
TextButton(
onPressed: () => Navigator.pop(context, 'OK'),
child: const Text('OK'),
),
],
),
),
...
這里onTap會(huì)調(diào)用一個(gè)showDialog來(lái)彈出一個(gè)對(duì)話(huà)框,運(yùn)行之后結(jié)果如下:
會(huì)動(dòng)的組件
在上面的例子中,我們用手去tap按鈕是沒(méi)有互動(dòng)效果的,也就是說(shuō)按鈕是不會(huì)變化的。
那么有沒(méi)有可能模擬手指的按壓效果呢?
答案是肯定的,flutter為我們提供了一個(gè)InkWell組件,這樣手指按壓下組件會(huì)產(chǎn)生波紋的效果。
那么InkWell和GestureDetector有什么聯(lián)系呢?
InkWell和GestureDetector很類(lèi)似,都提供了對(duì)手勢(shì)的支持。
在InkWell中提供了多種GestureTapCallback接口,用接收手勢(shì)的回調(diào),非常的方便。
在使用上,InkWell和GestureDetector也很類(lèi)似,我們可以完全照搬GestureDetector的用法。
還是上面的例子,我們可以將GestureDetector替換成為InkWell,如下所示:
Widget build(BuildContext context) {
return InkWell(
onTap: () {
ScaffoldMessenger.of(context).showSnackBar(const SnackBar(
content: Text('Tap'),
));
},
child: const Padding(
padding: EdgeInsets.all(12.0),
child: Text('Flat Button'),
),
);
}
這里,為了更好的觀(guān)察手勢(shì)按壓之后的效果,這里onTap選擇展示一個(gè)flutter自帶的SnackBar。
可刪除的組件
在app中的手勢(shì)應(yīng)用上,有一個(gè)比較常見(jiàn)的用法就是在list列表中,向左滑動(dòng)一個(gè)item,會(huì)出現(xiàn)刪除的按鈕,這種滑動(dòng)刪除的效果,如何在flutter中實(shí)現(xiàn)呢?
flutter提供了一個(gè)Dismissible的組件來(lái)實(shí)現(xiàn)這個(gè)效果。
我們先來(lái)看下Dismissible的定義:
class Dismissible extends StatefulWidget {
const Dismissible({
required Key key,
required this.child,
this.background,
this.secondaryBackground,
this.confirmDismiss,
this.onResize,
this.onUpdate,
this.onDismissed,
this.direction = DismissDirection.horizontal,
this.resizeDuration = const Duration(milliseconds: 300),
this.dismissThresholds = const <DismissDirection, double>{},
this.movementDuration = const Duration(milliseconds: 200),
this.crossAxisEndOffset = 0.0,
this.dragStartBehavior = DragStartBehavior.start,
this.behavior = HitTestBehavior.opaque,
}) : assert(key != null),
assert(secondaryBackground == null || background != null),
assert(dragStartBehavior != null),
super(key: key);
可以看到Dismissible是一個(gè)StatefulWidget,它有兩個(gè)必須的參數(shù)分別是key和child。
key用來(lái)標(biāo)記要?jiǎng)h除item的id,child是可以滑動(dòng)刪除的組件。
為了演示方便,我們使用ListView來(lái)展示如何使用Dismissible。
首先我們構(gòu)建一個(gè)items的list,里面包含了每個(gè)item要展示的內(nèi)容:
final items = List<String>.generate(10, (i) => '動(dòng)物 ${i + 1}');
然后使用ListView的builder方法來(lái)構(gòu)建items。并且將每個(gè)items封裝到Dismissible中去:
body: ListView.builder(
itemCount: items.length,
itemBuilder: (context, index) {
final item = items[index];
return Dismissible(
key: Key(item),
onDismissed: (direction) {
setState(() {
items.removeAt(index);
});
ScaffoldMessenger.of(context)
.showSnackBar(SnackBar(content: Text('$item 被刪除了')));
},
child: ListTile(
title: Text(item),
),
);
},
)
這里Dismissible的child是ListTile組件,里面的具體內(nèi)容就是Text。
現(xiàn)在Dismissible實(shí)際上就可以工作了,當(dāng)你滑動(dòng)ListTile的時(shí)候,對(duì)應(yīng)的item就會(huì)被刪除。
為了明顯起見(jiàn),我們可以給Dismissible添加一個(gè)background屬性,這樣滑動(dòng)刪除的時(shí)候就有了一個(gè)背景顏色:
background: Container(color: Colors.red),
另外,Dismissible還有一個(gè)confirmDismiss屬性,可以用來(lái)判斷是否真的要滑動(dòng)刪除,比如我們只允許從右到左滑動(dòng)刪除,那么可以這樣做:
Dismissible(
...
confirmDismiss:confirmResult,
...
)
Future<bool> confirmResult(DismissDirection direction) async {
if(direction == DismissDirection.endToStart){
return true;
}
return false;
}
這里的confirmResult是一個(gè)異步函數(shù),它接收一個(gè)DismissDirection的參數(shù),這個(gè)參數(shù)表示的是滑動(dòng)刪除的方向,我們可以通過(guò)這個(gè)方向來(lái)判斷是否真正的進(jìn)行刪除操作。
總結(jié)
以上就是日常手勢(shì)的基本使用了,我們可以通過(guò)GestureDetector,InkWell和Dismissible來(lái)和手勢(shì)進(jìn)行結(jié)合來(lái)實(shí)現(xiàn)相應(yīng)的功能。
原文鏈接:https://juejin.cn/post/7178827356436430905
相關(guān)推薦
- 2022-04-04 asp.net使用原生控件實(shí)現(xiàn)自定義列導(dǎo)出功能的方法_實(shí)用技巧
- 2022-06-25 Qt一個(gè)進(jìn)程運(yùn)行另一個(gè)進(jìn)程的實(shí)現(xiàn)方法_C 語(yǔ)言
- 2022-05-27 Linux?創(chuàng)建oracle數(shù)據(jù)庫(kù)的詳細(xì)過(guò)程_oracle
- 2022-01-29 yii restfull api 訪(fǎng)問(wèn)404
- 2021-12-15 Android?studio導(dǎo)出APP測(cè)試包和構(gòu)建正式簽名包_Android
- 2022-07-13 Docker之Harbor私有倉(cāng)庫(kù)
- 2023-03-03 C++?高精度乘法運(yùn)算的實(shí)現(xiàn)_C 語(yǔ)言
- 2022-11-27 Python?OpenCV實(shí)現(xiàn)圖像增強(qiáng)操作詳解_python
- 最近更新
-
- window11 系統(tǒng)安裝 yarn
- 超詳細(xì)win安裝深度學(xué)習(xí)環(huán)境2025年最新版(
- Linux 中運(yùn)行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲(chǔ)小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎(chǔ)操作-- 運(yùn)算符,流程控制 Flo
- 1. Int 和Integer 的區(qū)別,Jav
- spring @retryable不生效的一種
- Spring Security之認(rèn)證信息的處理
- Spring Security之認(rèn)證過(guò)濾器
- Spring Security概述快速入門(mén)
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權(quán)
- redisson分布式鎖中waittime的設(shè)
- maven:解決release錯(cuò)誤:Artif
- restTemplate使用總結(jié)
- Spring Security之安全異常處理
- MybatisPlus優(yōu)雅實(shí)現(xiàn)加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務(wù)發(fā)現(xiàn)-Nac
- Spring Security之基于HttpR
- Redis 底層數(shù)據(jù)結(jié)構(gòu)-簡(jiǎn)單動(dòng)態(tài)字符串(SD
- arthas操作spring被代理目標(biāo)對(duì)象命令
- Spring中的單例模式應(yīng)用詳解
- 聊聊消息隊(duì)列,發(fā)送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠(yuǎn)程分支