Flutter 事件/通知[GestureDetector,InkWell,Snackbar]

Flutter 事件与通知

GestureDetector

GestureDetector 可以进行手势检测,共有7种类型事件。比如点击一次、双击、长按、垂直滑动及水平滑动等

属性 类型 简述
onTapDown GestureTapDownCallback 手指按下时触发
onTapUp GestureTapUpCallback 手指抬起时触发
onTap GestureTapCallback 单击屏幕时触发
onTapCancel GestureTapCancelCallback 没有完成Tap的动作时触发
onDoubleTap GestureTapCallback 快速双击屏幕时触发
onLongPress GestureLongPressCallback 长按屏幕时触发
onLongPressStart GestureLongPressStartCallback 监听长按事件的开始
onLongPressMoveUpdate GestureLongPressMoveUpdateCallback 长按屏幕且移动手指时触发
onLongPressUp GestureLongPressUpCallback 手指完全离开屏幕时触发
onLongPressEnd GestureLongPressEndCallback 手指开始离开屏幕时触发
onVerticalDragDown GestureDragDownCallback 手指按下并在垂直方向上移动时触发
onVerticalDragStart GestureDragStartCallback 触摸点开始在垂直方向上移动时触发(在onVerticalDragDown之后)
onVerticalDragUpdate GestureDragUpdateCallback 触摸点在垂直方向上移动时触发
onVerticalDragEnd GestureDragEndCallback 停止移动,且该拖拽操作就被认为是完成了时触发
onVerticalDragCancel GestureDragCancelCallback 突然停止拖拽时触发
onHorizontalDragDown GestureDragDownCallback 参见onVerticalDragDown,为水平方向
onHorizontalDragStart GestureDragStartCallback 参见onVerticalDragDown,为水平方向
onHorizontalDragUpdate GestureDragUpdateCallback 参见onVerticalDragDown,为水平方向
onHorizontalDragEnd GestureDragEndCallback 参见onVerticalDragDown,为水平方向
onHorizontalDragCancel GestureDragCancelCallback 参见onVerticalDragDown,为水平方向
onPanDown GestureDragDownCallback 手指接触屏幕,并且可能开始移动时触发
onPanStart GestureDragStartCallback 触摸点开始移动时触发
onPanUpdate GestureDragUpdateCallback 触摸点不断移动时触发
onPanEnd GestureDragEndCallback 操作完成手指离开屏幕时触发
onPanCancel GestureDragCancelCallback 先前触发onPanDown的指针未完成时触发
onScaleStart GestureScaleStartCallback 触摸屏幕开始缩放操作时触发
onScaleUpdate GestureScaleUpdateCallback 缩放过程中的监听
onScaleEnd GestureScaleEndCallback 手指离开屏幕,缩放完成时触发
onForcePressStart GestureForcePressStartCallback 触摸屏幕且有足够压力时触发(仅在具有压力检测的屏幕设备支持)
onForcePressPeak GestureForcePressPeakCallback 触摸屏幕压力达到最大时触发(需设备支持)
onForcePressUpdate GestureForcePressUpdateCallback 有足够的压力并在屏幕上移动时触发(需设备支持)
onForcePressEnd GestureForcePressEndCallback 离开屏幕时触发(需设备支持)
behavior HitTestBehavior 在命中测试期间,此手势检测器应如何表现
excludeFromSemantics bool 是否从语义树中排除这些手势。 例如,用于显示工具提示的长按手势被排除在外,因为工具提示本身直接包含在语义树中,因此具有显示该工具提示的手势将导致信息重复
dragStartBehavior DragStartBehavior 设定处理拖动开始行为的方式

需要注意,GestureDetector并不会监听所有的手势,只有传入的回调非空时,才会监听。所以,如果想要禁用某个手势时,可将对应的回调函数设置为null

另外,GestureDetector的某些事件是互斥的,不能同时存在,例如onVerticalUpdateonHorizontalUpdateonPanUpdate这三个事件不能同时存在,onPanUpdateonScaleUpdate也不能同时存在。

测试手势处理回调

GestureDetector( child: Container( width: 300.0, height: 500.0, color: Colors.amber, ), onTapDown: (_) => debugPrint("onTapDown"), onTapUp: (_) => debugPrint("onTapUp"), onTap: () => debugPrint("onTap"), onTapCancel: () => debugPrint("onTapCancel"), onDoubleTap: () => debugPrint("onDoubleTap"), onLongPress: () => debugPrint("onLongPress"), onLongPressUp: () => debugPrint("onLongPressUp"), onVerticalDragDown: (_) => debugPrint("onVerticalDragDown"), onVerticalDragStart: (_) => debugPrint("onVerticalDragStart"), onVerticalDragUpdate: (_) => debugPrint("onVerticalDragUpdate"), onVerticalDragEnd: (_) => debugPrint("onVerticalDragEnd"), onVerticalDragCancel: () => debugPrint("onVerticalDragCancel"), onHorizontalDragDown: (_) => debugPrint("onHorizontalDragDown"), onHorizontalDragStart: (_) => debugPrint("onHorizontalDragStart"), onHorizontalDragUpdate: (_) => debugPrint("onHorizontalDragUpdate"), onHorizontalDragEnd: (_) => debugPrint("onHorizontalDragEnd"), onHorizontalDragCancel: () => debugPrint("onHorizontalDragCancel"), onPanDown: (_) => debugPrint("onPanDown"), onPanStart: (_) => debugPrint("onPanStart"), onPanUpdate: (_) => debugPrint("onPanUpdate"), onPanEnd: (_) => debugPrint("onPanEnd"), onPanCancel: () => debugPrint("onPanCancel"), onScaleStart: (_) => debugPrint("onScaleStart"), onScaleUpdate: (_) => debugPrint("onScaleUpdate"), onScaleEnd: (_) => debugPrint("onScaleEnd"), )

通过手势处理实现一个拖动示例

 
class _HomePageState extends State<HomePage> { double _left = 0.0; double _top = 0.0; GlobalKey _gKey = GlobalKey(); double stackWidth = 0.0; double stackHeight = 0.0; @override void initState() { super.initState(); // 注册一个回调,当屏幕渲染第一帧的时候回调 WidgetsBinding.instance.addPostFrameCallback((_){ stackWidth = _gKey.currentContext.size.width; stackHeight = _gKey.currentContext.size.height; }); } @override Widget build(BuildContext context) { print("_HomePageState build ..."); return Scaffold( appBar: AppBar( title: Text("Flutter Widget"), ), body: GestureDetector( onPanUpdate: (DragUpdateDetails details){ setState(() { // 边界检查 if(_left + 200 > stackWidth){ _left = stackWidth- 200; }else if(_left < 0){ _left = 0; } else{ _left += details.delta.dx; } if(_top + 200 > stackHeight){ _top = stackHeight- 200; }else if(_top < 0){ _top = 0; }else{ _top += details.delta.dy; } }); }, child: Stack( key: _gKey, children: <Widget>[ Positioned( left: _left, top: _top, width: 200.0, height: 200.0, child: Container( color: Colors.amber, ), ) ], ), ), ); }

缩放示例

class _ScaleWidgetState extends State<ScaleWidget>{ double _width = 300.0; double _height = 200.0; @override Widget build(BuildContext context) { return Center( child: GestureDetector( child: Container( width: _width, height: _height, color: Colors.pink, ), onScaleUpdate: (e) { print(e); setState(() { // 限制缩放比例在0.7-1.2之间,超过范围则变为原大小 _width = 300* e.scale.clamp(0.7, 1.2); _height = 200*e.scale.clamp(0.7, 1.2); }); }, ) ); } }

InkWell

具有水波纹效果(或称为溅墨效果)的点击事件控件。能处理的触摸事件很少,如需处理复杂的手势事件,应使用GestureDetector。

需要注意,当InkWell的父控件设置了背景色时,是看不到溅墨效果效果的,此时需要进行特殊处理,当使用InkWell包裹image时,也无法显示出溅墨效果,这时建议使用Ink.Image控件。

// 需使用Matetial 以及 Ink控件包裹 Material( child: Ink( decoration: BoxDecoration( color: Colors.blue, borderRadius: BorderRadius.circular(10) ), child: InkWell( onTap: (){ print("onTap..."); }, child: Container( padding: EdgeInsets.symmetric(horizontal: 16,vertical: 6), child: Text("这是按钮",style: TextStyle(color: Colors.white),), ), ), ), )

如需取消溅墨效果,可进行如下设置

// 设置highlightColor和radius取消溅墨效果 InkWell( highlightColor: Colors.transparent, radius: 0.0, child: Text( "click me", ), onTap: () { print("onTap"); }, ),

Snackbar

它是Material Design设计中的一个轻量级消息通知控件。

属性 类型 简述
content Widget 展示的内容
backgroundColor Color 背景色
elevation double 阴影高度
shape ShapeBorder 形状
behavior SnackBarBehavior 位置,SnackBarBehavior.fixed 固定在底部;SnackBarBehavior.floating显示在底部导航栏上方
action SnackBarAction 执行的动作(相当于按钮)
duration Duration 停留时间
animation animation 显示或隐藏的动画效果
onVisible VoidCallback 显示时的回调
Scaffold.of(context).showSnackBar(SnackBar( content: Text('这是一个 SnackBar'), backgroundColor: Colors.black26, duration: Duration(seconds: 1), behavior: SnackBarBehavior.floating, action: SnackBarAction( label: '我是按钮', onPressed: () { print('点击了按钮'); }), ));

小结:

  • 显示Snackbar :Scaffold.of(context).showSnackBar(snackBar)
  • 隐藏当前的SnackBarScaffold.of(context).hideCurrentSnackBar()
THE END
喜欢就支持一下吧
点赞12 分享