在大前端的開發中,必然存在各類各樣和用戶交互的狀況:好比手指點擊、手指滑動、雙擊、長按等等。html
全部內容首發於公衆號:coderwhy前端
在Flutter中,手勢有兩個不一樣的層次:vue
Pointer 表明的是人機界面交互的原始數據。一共有四種指針事件:web
PointerDownEvent
指針在特定位置與屏幕接觸
PointerMoveEvent
指針從屏幕的一個位置移動到另一個位置
PointerUpEvent
指針與屏幕中止接觸
PointerCancelEvent
指針由於一些特殊狀況被取消
Pointer的原理是什麼呢?算法
在指針落下時,框架作了一個 hit test 的操做,肯定與屏幕發生接觸的位置上有哪些Widget以及分發給最內部的組件去響應;api
事件會沿着最內部的組件向組件樹的根冒泡分發;數據結構
而且不存在用於取消或者中止指針事件進一步分發的機制;app
原始指針事件使用Listener來監聽:框架
class HomeContent extends StatelessWidget {
@override Widget build(BuildContext context) { return Center( child: Listener( child: Container( width: 200, height: 200, color: Colors.red, ), onPointerDown: (event) => print("手指按下:$event"), onPointerMove: (event) => print("手指移動:$event"), onPointerUp: (event) => print("手指擡起:$event"), ), ); } } 複製代碼
Gesture是對一系列Pointer的封裝,官方建議開發中儘量使用Gesture,而不是Pointerless
Gesture分層很是多的種類:
點擊:
雙擊:
長按:
縱向拖拽:
橫線拖拽:
移動:
onHorizontalDragStart
或者
onVerticalDragStart
,該回調方法會引起崩潰;
onHorizontalDragUpdate
或者
onVerticalDragUpdate
,該回調方法會引起崩潰。
onHorizontalDragEnd
或者
onVerticalDragEnd
,該回調方法會引起崩潰。
從Widget的層面來監聽手勢,咱們須要使用:GestureDetector
class HYHomePage extends StatelessWidget {
@override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text("手勢測試"), ), body: GestureDetector( child: Container( width: 200, height: 200, color: Colors.red, ), onTap: () { }, onTapDown: (detail) { print(detail.globalPosition); print(detail.localPosition); }, onTapUp: (detail) { print(detail.globalPosition); print(detail.localPosition); } ), ); } } 複製代碼
在組件之間若是有事件須要傳遞,一方面能夠一層層來傳遞,另外一方面咱們也可使用一個EventBus工具來完成。
其實EventBus在Vue、React中都是一種很是常見的跨組件通訊的方式:
這裏咱們直接選擇第三方的EventBus:
dependencies:
event_bus: ^1.1.1 複製代碼
第一:咱們須要定義一個但願在組件之間傳遞的對象:
class UserInfo {
String nickname; int level; UserInfo(this.nickname, this.level); } 複製代碼
第二:建立一個全局的EventBus對象
final eventBus = EventBus();
複製代碼
第三:在某個Widget中,發出事件:
class HYButton extends StatelessWidget {
@override Widget build(BuildContext context) { return RaisedButton( child: Text("HYButton"), onPressed: () { final info = UserInfo("why", 18); eventBus.fire(info); }, ); } } 複製代碼
第四:在某個Widget中,監聽事件
class HYText extends StatefulWidget {
@override _HYTextState createState() => _HYTextState(); } class _HYTextState extends State<HYText> { String message = "Hello Coderwhy"; @override void initState() { super.initState(); eventBus.on<UserInfo>().listen((data) { setState(() { message = "${data.nickname}-${data.level}"; }); }); } @override Widget build(BuildContext context) { return Text(message, style: TextStyle(fontSize: 30),); } } 複製代碼
備註:全部內容首發於公衆號,以後除了Flutter也會更新其餘技術文章,TypeScript、React、Node、uniapp、mpvue、數據結構與算法等等,也會更新一些本身的學習心得等,歡迎你們關注