本文目录
前言
GestureDetector基本用法
常用事件
监听事件实现缩放
监听事件实现拖拽
事件通知
前言
在Flutter开发App的过程中,我们除了需要灵活的使用各种组件之外,还需要掌握手势的识别,比如我们常常需要在操作App的时候使用到缩放,双击,放大,缩小等操作,这些Flutter都给我们提供了监听的组件GestureDetector。这篇博文将详细介绍GestureDetector手势识别的使用规则。(拖动手势监听)
GestureDetector基本用法
我们前面提到过,在Flutter开发中,一切皆是组件,所以GestureDetector同样是一个组件,我们使用它,通常是作为一个父Widget包裹一个子Widget外面(也就是你需要捕捉那个组件的手势,就把GestureDetector套在外外面),而内部我们通过onTap回调来实现其点击的效果,代码如下:
GGestureDetector(
onTap:(){
print("tap");
},
child:Container{
padding:EdgeInsets.all(20),
decoration:BoxDecoration(
color:Theme.of(context).buttonColor,
borderRadius:BorderRadius.circular(8.0),
),
child:new Text("文本"),
}
);
比如上面的代码就是改造Text组件成为按钮的方式,这里捕捉了点击事件。
常用事件
GestureDetector手势识别不仅仅只有onTap事件,还有很多很多的常用事件,博主通过一张表格将它们全部列举了出来,方便大家查阅:
虽然说上面表格非常详细,但其中有些事件是互斥的,并不能同时存在,比如onVerticalUpdate,onHorizontalUpdate,onPanUpdate这些三个事件都不能同时存在,否则会报错。
另外,onPanUpdate和onScaleUpdate也不能同时存在,这是因为在Gesture识别器里,Scale操作是Pan操作的超集。
监听事件实现缩放
既然我们了解了如何使用这些事件,那么,我们就应该实践起来,这里小编将用上面的事件实现一个缩放效果,代码如下:
class _MyHomePageState extends State<MyHomePage>{
double _top=0.0;
double _left=0.0;
double _size=100.0;
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: new Text("忽略事件"),),
body: Stack(
children: <Widget>[
Positioned(
top: this._top,
left: this._left,
child: GestureDetector(
child: FlutterLogo(
size: this._size,
),
onScaleUpdate: (e){
setState(() {
this._size=300*e.scale.clamp(.5, 10.0);////缩放倍数在0.5到10倍之间
});
},
),
),
],
),
);
}
}
代码非常的简单,就是缩放FlutterLogo的大小,实现的效果如下图所示:
监听事件实现拖拽
既然我们已经了解这么多事件,不妨多来一个事件,也就是App中常用的拖拽操作,代码如下(略微改改上上面的代码就行):
class _MyHomePageState extends State<MyHomePage>{
double _top=0.0;
double _left=0.0;
double _size=100.0;
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: new Text("忽略事件"),),
body: Stack(
children: <Widget>[
Positioned(
top: this._top,
left: this._left,
child: GestureDetector(
child: FlutterLogo(
size: this._size,
),
onScaleUpdate: (e){
setState(() {
this._size=300*e.scale.clamp(.5, 10.0);////缩放倍数在0.5到10倍之间
});
},
),
),
],
),
);
}
}
仅仅改变了事件的代码,前面说过onPanUpdate与onScaleUpdate不能同时存在,所以不能直接添加事件,需要删除onScaleUpdate后在添加。
事件通知
Notification是“通知”的意思,这和Android中不一样。在Flutter里,Notification会沿着当前的context节点从下往上传递,所有父节点都可以通过NotificationListener来监听通知,这种由子向父的传递方式,我们称为“通知冒泡”,并继承至Notification,而父Widget使用NotificationListener进行监听并捕获通知。常用的NotificatioListener有LayoutChangeNotification,SizeChangedLayoutNotifier,ScrollNotification等。比如本篇将监听ListView滚动状态:是通过NotificationListener里的onNotification回调方法来判断状态。代码如下:
class _MyHomePageState extends State<MyHomePage> {
String _message = "我是通知";
void _onScrollStart(ScrollMetrics scrollMetrics){
print(scrollMetrics.pixels);
setState(() {
this._message="滚动开始";
});
}
void _onScrollEnd(ScrollMetrics scrollMetrics){
print(scrollMetrics.pixels);
setState(() {
this._message="滚动结束";
});
}
void _onScrollUpdate(ScrollMetrics scrollMetrics){
print(scrollMetrics.pixels);
setState(() {
this._message="滚动进行时";
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: new Text("事件通知"),
),
body: Column(
children: <Widget>[
Container(
height: 50.0,
color: Colors.green,
child: Center(
child: new Text(this._message),
),
),
Expanded(
child: NotificationListener<ScrollNotification>(
// ignore: missing_return
onNotification: (scrollNotification) {
if (scrollNotification is ScrollStartNotification) {
this._onScrollStart(scrollNotification.metrics);
} else if (scrollNotification is ScrollUpdateNotification) {
this._onScrollUpdate(scrollNotification.metrics);
} else if (scrollNotification is ScrollEndNotification) {
this._onScrollEnd(scrollNotification.metrics);
}
},
child: ListView.builder(
itemCount: 30,
itemBuilder: (context, index) {
return ListTile(title: Text("索引:$index"),);
}),
),
),
],
),
);
}
}
实现效果如下图所示,代码很好理解,这里就不在赘述了:
学习分享,共勉
题外话,毕竟我在三星小米工作多年,深知技术改革和创新的方向,Flutter作为跨平台开发技术、Flutter以其美观、快速、高效、开放等优势迅速俘获人心,但很多FLutter兴趣爱好者进阶学习确实资料,今天我把我搜集和整理的这份学习资料分享给有需要的人,若有关Flutter学习进阶可以与我在Flutter跨平台开发终极之选交流群一起讨论交流。下载地址:https://shimo.im/docs/yTD3t8Pjq3XJtGv8
下载地址:https://shimo.im/docs/yTD3t8Pjq3XJtGv8
原文作者:李元静
原文链接:CSDN-专业IT技术社区-登录
来源:CSDN