Flutter實(shí)現(xiàn)手勢(shì)識(shí)別功能詳解方法
GestureDetector
GestureDetector 是手勢(shì)識(shí)別的組件,可以識(shí)別點(diǎn)擊、雙擊、長(zhǎng)按事件、拖動(dòng)、縮放等手勢(shì)
點(diǎn)擊事件
點(diǎn)擊相關(guān)事件包括:
- onTapDown:按下時(shí)回調(diào)。
- onTapUp:抬起時(shí)回調(diào)。
- onTap:點(diǎn)擊事件回調(diào)。
- onTapCancel:點(diǎn)擊取消事件回調(diào)。
按下然后抬起調(diào)用順序
onTapDown-> onTapUp-> onTap
按下后移動(dòng)調(diào)用順序
onTapDown-> onTapCancel
示例
class _YcHomeBodyState extends State<YcHomeBody> {
String desc = '';
Color containerColor = Colors.red;
@override
Widget build(BuildContext context) {
return GestureDetector(
child: Column(
children: [
Container(
width: 420,
height: 330,
color: containerColor,
),
const SizedBox(
width: 100,
height: 20,
),
Text("點(diǎn)擊事件:$desc")
],
),
onTapDown: (TapDownDetails tapDownDetails) {
setState(() {
desc += '按下,';
containerColor = Colors.blue;
});
},
onTapUp: (TapUpDetails tapUpDetails) {
setState(() {
desc += '抬起,';
containerColor = Colors.red;
});
},
onTap: () {
setState(() {
desc += '點(diǎn)擊,';
containerColor = Colors.yellow;
});
},
onTapCancel: () {
setState(() {
desc += '取消,';
containerColor = Colors.pink;
});
},
);
}
}
雙擊事件
雙擊是快速且連續(xù)2次在同一個(gè)位置點(diǎn)擊,雙擊監(jiān)聽(tīng)使用onDoubleTap方法
return GestureDetector(
child: Column(
children: [
Container(
width: 420,
height: 330,
color: containerColor,
),
const SizedBox(
width: 100,
height: 20,
),
Text("點(diǎn)擊事件:$desc")
],
),
onDoubleTap: () {
setState(() {
desc = '雙擊了';
});
},
長(zhǎng)按事件
長(zhǎng)按事件(LongPress)包含長(zhǎng)按開(kāi)始、移動(dòng)、抬起、結(jié)束事件,說(shuō)明如下:
- onLongPressStart:長(zhǎng)按開(kāi)始事件回調(diào)。
- onLongPressMoveUpdate:長(zhǎng)按移動(dòng)事件回調(diào)。
- onLongPressUp:長(zhǎng)按抬起事件回調(diào)。
- onLongPressEnd:長(zhǎng)按結(jié)束事件回調(diào)。
- onLongPress:長(zhǎng)按事件回調(diào)。
示例
return GestureDetector(
child: Column(
children: [
Container(
width: 420,
height: 330,
color: containerColor,
),
const SizedBox(
width: 100,
height: 20,
),
Text("點(diǎn)擊事件:$desc")
],
),
onLongPressStart: (v) {
setState(() {
desc += '長(zhǎng)按開(kāi)始,';
print("長(zhǎng)按開(kāi)始:$v");
});
},
onLongPressMoveUpdate: (v) {
setState(() {
desc += '長(zhǎng)按移動(dòng),';
print("長(zhǎng)按移動(dòng):$v");
});
},
onLongPressUp: () {
setState(() {
desc += '長(zhǎng)按抬起,';
print("長(zhǎng)按抬起");
});
},
onLongPressEnd: (v) {
setState(() {
desc += '長(zhǎng)按結(jié)束,';
print("長(zhǎng)按結(jié)束:$v");
});
},
onLongPress: () {
setState(() {
desc += '長(zhǎng)按回調(diào),';
print("長(zhǎng)按回調(diào)");
});
});
執(zhí)行順序
1、長(zhǎng)按開(kāi)始->回調(diào)->結(jié)束->抬起
2、長(zhǎng)按開(kāi)始->回調(diào)->移動(dòng)->結(jié)束->抬起
水平/垂直拖動(dòng)事件
垂直/水平拖動(dòng)事件包括按下、開(kāi)始、移動(dòng)更新、結(jié)束、取消事件,以垂直為例說(shuō)明如下:
- onVerticalDragDown:垂直拖動(dòng)按下事件回調(diào)
- onVerticalDragStart:垂直拖動(dòng)開(kāi)始事件回調(diào)
- onVerticalDragUpdate:指針移動(dòng)更新事件回調(diào)
- onVerticalDragEnd:垂直拖動(dòng)結(jié)束事件回調(diào)
- onVerticalDragCancel:垂直拖動(dòng)取消事件回調(diào)
GestureDetector(
onVerticalDragStart: (v) => print('onVerticalDragStart'),
onVerticalDragDown: (v) => print('onVerticalDragDown'),
onVerticalDragUpdate: (v) => print('onVerticalDragUpdate'),
onVerticalDragCancel: () => print('onVerticalDragCancel'),
onVerticalDragEnd: (v) => print('onVerticalDragEnd'),
child: Center(
child: Container(
width: 200,
height: 200,
color: Colors.red,
),
),
)縮放事件
縮放(Scale)包含縮放開(kāi)始、更新、結(jié)束。說(shuō)明如下:
- onScaleStart:縮放開(kāi)始事件回調(diào)。
- onScaleUpdate:縮放更新事件回調(diào)。
- onScaleEnd:縮放結(jié)束事件回調(diào)。
GestureDetector(
onScaleStart: (v) => print('onScaleStart'),
onScaleUpdate: (ScaleUpdateDetails v) => print('onScaleUpdate'),
onScaleEnd: (v) => print('onScaleEnd'),
child: Center(
child: Container(
width: 200,
height: 200,
color: Colors.red,
),
),
)InkWell
InkWell 組件在用戶(hù)點(diǎn)擊時(shí)出現(xiàn)“水波紋”效果。事件和屬性挺多的,就看一下常用的
設(shè)置水波紋顏色
點(diǎn)擊和長(zhǎng)按都能夠觸發(fā)水波紋,點(diǎn)擊波紋效果快,長(zhǎng)按波紋效果慢
return InkWell(
onTap: (){
print("點(diǎn)擊了");
},
splashColor: Colors.red,
child: const Text('點(diǎn)擊InkWell,水波紋'),
);

給字體添加邊距和圓角邊框,擴(kuò)大“水波紋”效果:
Center(
child: InkWell(
onTap: () {
print("點(diǎn)擊了");
},
splashColor: Colors.red,
child: Container(
padding: const EdgeInsets.all(10),
decoration: BoxDecoration(
border: Border.all(color: Colors.red),
borderRadius: const BorderRadius.all(Radius.circular(20))),
child: const Text('點(diǎn)擊InkWell,水波紋'))),
);
可以看到水波紋會(huì)超出圓角,為了解決這個(gè)問(wèn)題可以使用Ink
Ink
Ink控件用于在[Material]控件上繪制圖像和其他裝飾,以便[InkWell]、[InkResponse]控件的“水波紋”效果在其上面顯示。
return Center(
child: Ink(
decoration: const BoxDecoration(
gradient: LinearGradient(
begin: Alignment.topLeft,
end: Alignment.bottomRight,
colors: [Color(0xFFDE2F21), Color(0xFFEC592F)]),
borderRadius: BorderRadius.all(Radius.circular(20))),
child: InkWell(
borderRadius: const BorderRadius.all(Radius.circular(20)),
child: Container(
padding: const EdgeInsets.symmetric(vertical: 8, horizontal: 20),
child: const Text(
'這是InkWell的點(diǎn)擊效果',
style: TextStyle(color: Colors.white),
),
),
onTap: () {},
),
));
}
總感覺(jué)有點(diǎn)復(fù)雜,InkWell 會(huì)導(dǎo)致水紋超出邊框,就需要外面再套一層組件,然后還要寫(xiě)個(gè)漸變,不知道咋形容。
Listener
Listener 是一個(gè)監(jiān)聽(tīng)指針事件的控件,比如按下、移動(dòng)、釋放、取消等指針事件,但Listener無(wú)法監(jiān)聽(tīng)鼠標(biāo)特有的事件,比如:移入、懸停、移出事件。鼠標(biāo)事件使用MouseRegion監(jiān)聽(tīng)。
通常情況下,監(jiān)聽(tīng)手勢(shì)事件使用GestureDetector,GestureDetector是更高級(jí)的手勢(shì)事件。
Listener的事件介紹如下:
- onPointerDown:按下時(shí)回調(diào)
- onPointerMove:移動(dòng)時(shí)回調(diào)
- onPointerUp:抬起時(shí)回調(diào)
Listener(
onPointerDown: (PointerDownEvent pointerDownEvent) {
print('$pointerDownEvent');
},
onPointerMove: (PointerMoveEvent pointerMoveEvent) {
print('$pointerMoveEvent');
},
onPointerUp: (PointerUpEvent upEvent) {
print('$upEvent');
},
child: Container(
height: 200,
width: 200,
color: Colors.blue,
alignment: Alignment.center,
),
)
常用屬性說(shuō)明如下:
position:相對(duì)屏幕的坐標(biāo)的偏移。
localPosition:相對(duì)當(dāng)前控件的偏移。
pressure:按壓力度。
delta:2次指針移動(dòng)事件的偏移。
orientation:指針移動(dòng)方向
案例
進(jìn)度按鈕
// 使用枚舉定義按鈕的狀態(tài)
enum ButtonStates { none, loading, done }
class YcHomeBody extends StatefulWidget {
const YcHomeBody({Key? key}) : super(key: key);
@override
State<YcHomeBody> createState() => _YcHomeBodyState();
}
class _YcHomeBodyState extends State<YcHomeBody> {
//定義按鈕的狀態(tài)
ButtonStates _buttonStates = ButtonStates.none;
@override
Widget build(BuildContext context) {
return Center(
child: MaterialButton(
color: Colors.blue,
textColor: Colors.white,
minWidth: 200,
height: 40,
//通過(guò)自定義方法,根據(jù)情況返回相應(yīng)的組件
child: _build(),
onPressed: () {
//點(diǎn)擊按鈕后將按鈕狀態(tài)變?yōu)榧虞d中
setState(() {
_buttonStates = ButtonStates.loading;
//延遲2s后將狀態(tài)變?yōu)橥瓿?
Future.delayed(const Duration(seconds: 2), () {
setState(() {
_buttonStates = ButtonStates.done;
});
});
});
},
),
);
}
//自定義方法
_build() {
if (_buttonStates == ButtonStates.none) {
//無(wú)狀態(tài)
return const Text("登錄");
} else if (_buttonStates == ButtonStates.loading) {
//進(jìn)度條組件
return const CircularProgressIndicator(
backgroundColor: Colors.white,
strokeWidth: 2,
);
} else if (_buttonStates == ButtonStates.done) {
return const Icon(
Icons.check,
color: Colors.white,
);
}
}
}
代碼看著很長(zhǎng)但是邏輯很簡(jiǎn)單,定義了一個(gè)枚舉類(lèi)型的按鈕類(lèi)型。一開(kāi)始類(lèi)型為無(wú)狀態(tài),此時(shí)顯示登錄;當(dāng)點(diǎn)擊按鈕后,狀態(tài)變?yōu)榧虞d中,顯示圓形進(jìn)度條組件;2s后將按鈕狀態(tài)變?yōu)榧虞d完成,現(xiàn)成完成的圖標(biāo)

到此這篇關(guān)于Flutter實(shí)現(xiàn)手勢(shì)識(shí)別功能詳解方法的文章就介紹到這了,更多相關(guān)Flutter手勢(shì)識(shí)別內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Gradle?Build?Cache引發(fā)的Task緩存編譯問(wèn)題
這篇文章主要為大家介紹了Gradle?Build?Cache引發(fā)的Task緩存編譯問(wèn)題,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-06-06
安卓Android6.0權(quán)限動(dòng)態(tài)獲取操作示例
這篇文章主要介紹了安卓Android6.0權(quán)限動(dòng)態(tài)獲取操作,結(jié)合實(shí)例形式分析了Android6.0針對(duì)權(quán)限的動(dòng)態(tài)獲取、授權(quán)等相關(guān)操作技巧,需要的朋友可以參考下2018-02-02
Android ScrollView嵌套橫向滑動(dòng)控件時(shí)沖突問(wèn)題
本篇文章主要介紹了Android ScrollView嵌套橫向滑動(dòng)控件時(shí)沖突問(wèn)題,具有一定的參考價(jià)值,有興趣的可以了解一下2017-08-08
Android?app啟動(dòng)節(jié)點(diǎn)與上報(bào)啟動(dòng)實(shí)例詳解
系統(tǒng)的啟動(dòng)過(guò)程非常復(fù)雜,下面這篇文章主要給大家介紹了關(guān)于Android?app啟動(dòng)節(jié)點(diǎn)與上報(bào)啟動(dòng)的相關(guān)資料,文中通過(guò)實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下2022-04-04
Android黑科技之讀取用戶(hù)短信+修改系統(tǒng)短信數(shù)據(jù)庫(kù)
這篇文章主要介紹了Android黑科技之讀取用戶(hù)短信+修改系統(tǒng)短信數(shù)據(jù)庫(kù) 的相關(guān)資料,需要的朋友可以參考下2015-12-12
Android實(shí)現(xiàn)屏幕各尺寸的獲取的示例
本篇文章主要介紹了Android實(shí)現(xiàn)屏幕各尺寸的獲取的示例,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2017-09-09
Android使用webView加載html頁(yè)面的詳細(xì)步驟
Android WebView是Android開(kāi)發(fā)中提供的一種用于顯示網(wǎng)頁(yè)內(nèi)容的組件,它可以加載網(wǎng)頁(yè)的url鏈接,也可以加載本地的html文件,下面這篇文章主要給大家介紹了關(guān)于Android使用webView加載html頁(yè)面的相關(guān)資料,需要的朋友可以參考下2024-06-06
Android衛(wèi)星菜單效果的實(shí)現(xiàn)方法
這篇文章主要介紹了Android衛(wèi)星菜單效果的實(shí)現(xiàn)方法,需要的朋友可以參考下2017-05-05

