思考一个问题,在 Flutter 中如何处理点击、长按等手势交互呢 🤔 ?github
事实上,Flutter 提供了多种处理手势交互的方案,本篇文章介绍一种比较通用和全能的方案: GestureDetector。bash
使用 GestureDetector 能够得到各类类型的点击事件回调,所以你能够建立出可以处理各类点击事件的 Widget 来。ide
如今,看看 GestureDetector 有些什么经常使用的交互事件吧:函数
onTap:单击post
onDoubleTap:双击ui
onLongPress:长按this
onTapUp:手指抬起来时spa
onTapDown:手指触碰屏幕时3d
onTapCancel:点击没有完成
onVerticalDragDown:手指刚接触屏幕时,随后开始垂直方向上的拖动
onVerticalDragStart:垂直方向上的拖动开始时
onVerticalDragUpdate:垂直方向上的拖动更新时
onVerticalDragEnd:垂直方向上的拖动结束时
onVerticalDragCancel:垂直拖动没有完成
onHorizontallyDragDown:手指刚接触屏幕时,随后开始水平方向上的拖动
onHorizontallyDragStart:水平方向上的拖动开始时
onHorizontallyDragUpdate:水平方向上的拖动更新时
onHorizontallyDragEnd:水平方向上的拖动结束时
onHorizontallyDragCancel:水平拖动没有完成
onScaleStart:开始缩放时,初始 scale 为 1.0
onScaleUpdate:缩放更新时
onScaleEnd:缩放结束
onPanDown:手指触摸屏幕时
onPanUpdate:手指移动时
onPanEnd:滑动结束时
使用 GestureDetector 建立一个可交互的 Widget。
class TapBox extends StatefulWidget {
final bool active;
// 定义一个函数,外界传入后可被调用
final ValueChanged<bool> onChanged;
TapBox({Key key, this.active, this.onChanged}) : super(key: key);
@override
State<StatefulWidget> createState() {
return _TabBox();
}
}
class _TabBox extends State<TapBox> {
bool _highlight = false;
void _handleTapDown(TapDownDetails details) {
setState(() {
_highlight = true;
});
}
void _handleTapUp(TapUpDetails details) {
setState(() {
_highlight = false;
});
}
void _handleTapCancel() {
setState(() {
_highlight = false;
});
}
void _handleTap() {
// 经过 widget 能够得到其成员变量
widget.onChanged(!widget.active);
}
Widget build(BuildContext context) {
// 把你的 Widget 使用 GestureDetector 包裹📦起来
return GestureDetector(
// 处理按下手势
onTapDown: _handleTapDown,
// 处理抬起手势
onTapUp: _handleTapUp,
// 处理点击手势
onTap: _handleTap,
// 处理取消手势
onTapCancel: _handleTapCancel,
child: Container(
child: Center(
child: Text(widget.active ? 'Active' : 'Inactive',
style: TextStyle(fontSize: 32.0, color: Colors.white)),
),
width: 200.0,
height: 200.0,
decoration: BoxDecoration(
color: widget.active ? Colors.lightGreen[700] : Colors.grey[600],
border: _highlight
? Border.all(
color: Colors.teal[700],
width: 10.0,
)
: null,
),
),
);
}
}
复制代码
你看,GestureDetector 也是一个 Widget,经过使用它来包裹目标 Widget,就使得目标 Widget 具备处理事件的能力。
使用这个 Widget。
class ParentWidget extends StatefulWidget {
@override
State<StatefulWidget> createState() {
return _ParentWidget();
}
}
class _ParentWidget extends State<ParentWidget> {
bool _active = false;
void _handleTapBoxChanged(bool newValue) {
setState(() {
_active = newValue;
});
}
@override
Widget build(BuildContext context) {
return Container(
child: TapBox(
active: _active,
// 传入函数
onChanged: _handleTapBoxChanged,
),
);
}
}
复制代码
运行效果: