配圖來自網絡,如侵必刪
在
Flutter
開發當中,我們可能會遇到下面的需求:
定位用戶手指當前處于的位置,以及點擊了多少次。
遇到這種需求,我們就需要使用指針事件
來幫我們實現。這篇博客分享指針事件
的知識,希望對看文章的小伙伴有所幫助。
指針事件
怎么獲取指針事件?這是一個很關鍵的問題,大概的實現思路是:
-
Flutter
應用中每個顯示在屏幕中的頁面都會被Listener
組件包裹,我們首先要獲取Listener
組件; - 我們通過
Listener
組件獲取用戶和屏幕交互的原始數據。
指針事件對象中存放了這個指針的位置、偏移量等用戶與設備屏幕交互的原始數據信息。
Listener組件源碼
const Listener({
Key? key,
this.onPointerDown, // 手指按下回調
this.onPointerMove, // 手指移動回調
this.onPointerUp, // 手指抬起回調
this.onPointerHover, // 懸停
this.onPointerCancel, // 觸摸事件取消回調
this.onPointerSignal, //
this.behavior = HitTestBehavior.deferToChild,
Widget? child,
})
Listener組件API
事件API | 事件描述 |
---|---|
onPointerDown | 用戶按下時回調的參數 |
onPointerMove | 用戶在屏幕上移動時的回調 |
PointerEvent | 用戶抬起手指回調的對象 |
簡單的代碼示例
import 'package:flutter/material.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: const MyHomePage(title: 'Listener Demo'),
);
}
}
class MyHomePage extends StatefulWidget {
const MyHomePage({Key? key, required this.title}) : super(key: key);
final String title;
@override
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
int downCounter = 0;
int upCounter = 0;
double x = 0.0;
double y = 0.0;
// 按下事件的處理方法
void incrementDown(PointerDownEvent event) {
updateLocation(event);
setState(() {
downCounter++;
});
}
// 抬起事件的處理方法
void incrementUp(PointerUpEvent event) {
updateLocation(event);
setState(() {
upCounter++;
});
}
// 移動事件的處理方法
void updateLocation(PointerEvent event) {
setState(() {
x = event.position.dx;
y = event.position.dy;
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Center(
child: ConstrainedBox(
constraints: BoxConstraints.tight(const Size(300, 200)),
child: Listener(
onPointerDown: incrementDown,
onPointerMove: updateLocation,
onPointerUp: incrementUp,
child: Container(
color: Colors.redAccent,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
const Text('按下抬起的次數:'),
Text('按下$downCounter次,抬起$upCounter次'),
Text(
'目前點擊的位置(${x.toStringAsFixed(2)},${y.toStringAsFixed(2)})')
],
),
),
),
),
),
);
}
}
小伙伴們可以直接復制上面的代碼運行。效果如下:
效果