- 监听屏幕触摸事件(Listener)
- PointerEvent(忽略事件)
- GestureDetector 手势点击
- 拖拽控件
- 缩放识别
- 事件竞争机制
- NotificationListener 监听滑动
1.监听屏幕触摸事件(Listener)
- onPointerDown 点击
- onPointerMove 移动
- onPointerUp 离开
- onPointerCancel 取消
Listener(
child: Container(
alignment: Alignment.center,
color: Colors.blue,
width: 240.0,
height: 120.0,
child: Text(
_opName,
style: TextStyle(color: Colors.white),
),
),
onPointerDown: (PointerDownEvent event) =>
_showEventText('onPointerDown'),
onPointerMove: (PointerMoveEvent event) =>
_showEventText('onPointerMove'),
onPointerUp: (PointerUpEvent event) => _showEventText('onPointerUp'),
onPointerCancel: (PointerCancelEvent event) =>
_showEventText('onPointerCancel'),
)
2.PointerEvent(忽略事件)
-
IgnorePointer
: ignoring是否忽略点击,默认true
不可以点击
-
AbsorbPointer : absorbing child 是否接受点击事件,
默认true
可以点击
import 'package:flutter/material.dart';
class PointerEventIgnorePage extends StatefulWidget {
@override
_PointerEventIgnorePageState createState() =>
new _PointerEventIgnorePageState();
}
class _PointerEventIgnorePageState extends State<PointerEventIgnorePage> {
bool _ignore = true;
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('忽略事件')),
body: Container(
alignment: AlignmentDirectional.center,
child: Column(
children: <Widget>[
Switch(
value: _ignore,
onChanged: (value) {
setState(() => _ignore = value);
},
),
GestureDetector(
onTap: () => print('GestureDetector Clicked!'),
child: IgnorePointer(
ignoring: _ignore,
child: RaisedButton(
onPressed: () => print('IgnorePointer Clicked!'),
child: Text('IgnorePointer'),
),
),
),
GestureDetector(
onTap: () => print('GestureDetector Clicked!'),
child: AbsorbPointer(
absorbing: _ignore,
child: RaisedButton(
onPressed: () => print('AbsorbPointer Clicked!'),
child: Text('AbsorbPointer'),
),
),
),
],
),
),
);
}
}
3.GestureDetector 手势点击
- onTap 点击
- onTapUp
- onTapDown
- onTapCancel
- onDoubleTap 双击
- onLongPress 长按
- onVerticalDragDown 拖拽
- onVerticalDragStart
- onVerticalDragUpdate
- onVerticalDragEnd
- onVerticalDragCancel
- onHorizontalDragDown
- onHorizontalDragStart
- onHorizontalDragUpdate
- onHorizontalDragEnd
- onHorizontalDragCancel
class GestureDetectorPage extends StatefulWidget {
@override
_GestureDetectorState createState() => new _GestureDetectorState();
}
class _GestureDetectorState extends State<GestureDetectorPage> {
String _opName = "未检测到操作";
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("GestureDetector手势识别"),
),
body: Center(
child: GestureDetector(
child: Container(
alignment: Alignment.center,
color: Colors.blue,
width: 240.0,
height: 120.0,
child: Text(
_opName,
style: TextStyle(color: Colors.white),
),
),
onTap: () => _showEventText("Tap"),
onTapUp: (e) => _showEventText("TapUp"),
onTapDown: (e) => _showEventText("TapDown"),
onTapCancel: () => _showEventText("TapCancel"),
onDoubleTap: () => _showEventText("DoubleTap"),
onLongPress: () => _showEventText("LongPress"),
onVerticalDragDown: (e) => _showEventText("onVerticalDragDown"),
onVerticalDragStart: (e) => _showEventText("onVerticalDragStart"),
onVerticalDragUpdate: (e) => _showEventText("onVerticalDragUpdate"),
onVerticalDragEnd: (e) => _showEventText("onVerticalDragEnd"),
onVerticalDragCancel: () => _showEventText("onVerticalDragCancel"),
onHorizontalDragDown: (e) => _showEventText("onHorizontalDragDown"),
onHorizontalDragStart: (e) => _showEventText("onHorizontalDragStart"),
onHorizontalDragUpdate: (e) => _showEventText("onHorizontalDragUpdate"),
onHorizontalDragEnd: (e) => _showEventText("onHorizontalDragEnd"),
onHorizontalDragCancel: () => _showEventText("onHorizontalDragCancel"),
// onPanDown: (e) => _showEventText("onPanDown"),
// onPanStart: (e) => _showEventText("onPanStart"),
// onPanUpdate: (e) => _showEventText("onPanUpdate"),
// onPanEnd: (e) => _showEventText("onPanEnd"),
// onScaleStart: (e) => _showEventText("onScaleStart"),
// onScaleUpdate: (e) => _showEventText("onScaleUpdate"),
// onScaleEnd: (e) => _showEventText("onScaleEnd"),
),
),
);
}
void _showEventText(String text) {
setState(() {
_opName = text;
});
print(_opName);
}
}
4.拖拽控件
效果图
拖拽
关键代码
import 'package:flutter/material.dart';
class DragPage extends StatefulWidget {
@override
_DragState createState() => new _DragState();
}
class _DragState extends State<DragPage> with SingleTickerProviderStateMixin {
double _top = 0.0;
double _left = 0.0;
double _size = 100.0;
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("拖拽控件"),
),
body: Stack(
children: <Widget>[
Positioned(
top: _top,
left: _left,
child: GestureDetector(
child: FlutterLogo(
size: _size,
),
onPanUpdate: (e) {
setState(() {
_left += e.delta.dx;
_top += e.delta.dy;
});
},
),
)
],
),
);
}
}
5.缩放识别
import 'package:flutter/material.dart';
class ScalePage extends StatefulWidget {
@override
_ScaleState createState() => new _ScaleState();
}
class _ScaleState extends State<ScalePage> {
double _size = 100.0;
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("缩放识别"),
),
body: Center(
child: GestureDetector(
child: Container(
alignment: Alignment.center,
child: FlutterLogo(size: _size,),
),
onScaleUpdate: (ScaleUpdateDetails e) {
setState(() {
_size = 300 * e.scale.clamp(.5, 10.0);
});
},
),
),
);
}
}
6.GestureRecognizer(对于不带点击事件的Widget,例如RichText)
关键代码
recognizer: _tapGestureRecognizer
..onTap = () {
showInSnackBar("built: 建造");
},
import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart';
class GestureRecognizerPage extends StatefulWidget {
@override
_GestureRecognizerState createState() => new _GestureRecognizerState();
}
class _GestureRecognizerState extends State<GestureRecognizerPage> {
TapGestureRecognizer _tapGestureRecognizer = new TapGestureRecognizer();
final GlobalKey<ScaffoldState> _scaffoldKey = new GlobalKey<ScaffoldState>();
@override
void dispose() {
_tapGestureRecognizer.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
key: _scaffoldKey,
appBar: AppBar(
title: Text("GestureRecognizer"),
),
body: Padding(
padding: EdgeInsets.all(10.0),
child: Column(
children: <Widget>[
Text.rich(
TextSpan(
children: [
TextSpan(
text: "Room is not ",
style: TextStyle(fontSize: 25.0),
),
TextSpan(
text: "built",
style: TextStyle(
fontSize: 25.0,
color: Colors.blue,
fontWeight: FontWeight.bold,
decoration: TextDecoration.underline,
decorationThickness: 3.0,
decorationColor: Colors.amber,
decorationStyle: TextDecorationStyle.solid,
),
recognizer: _tapGestureRecognizer
..onTap = () {
showInSnackBar("built: 建造");
},
),
TextSpan(
text: " in one day.",
style: TextStyle(fontSize: 25.0),
),
],
),
),
],
),
),
);
}
void showInSnackBar(String value) {
_scaffoldKey.currentState.showSnackBar(
new SnackBar(
content: new Text(
value,
style: TextStyle(fontSize: 25.0),
),
),
);
}
}
7.事件竞争机制
import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart';
class BothDirectionPage extends StatefulWidget {
@override
_BothDirectionState createState() => new _BothDirectionState();
}
class _BothDirectionState extends State<BothDirectionPage> {
double _top = 0.0;
double _left = 0.0;
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("事件竞争机制"),
),
body: Stack(
children: <Widget>[
Positioned(
top: _top,
left: _left,
child: GestureDetector(
child: FlutterLogo(
size: 100,
),
onVerticalDragUpdate: (DragUpdateDetails e) {
setState(() {
_top += e.delta.dy;
});
print("垂直胜出");
},
onHorizontalDragUpdate: (DragUpdateDetails e) {
setState(() {
_left += e.delta.dx;
});
print("水平胜出");
},
onTapDown: (e) {
print("按下");
},
onTapUp: (e) {
print("松开");
},
onHorizontalDragEnd: (e) {
print("水平移动结束");
},
onVerticalDragEnd: (e) {
print("垂直移动结束");
},
),
)
],
),
);
}
}
8.NotificationListener
监听滚动通知<ScrollNotification>
- Scroll Start
- Scroll Update
- Scroll End
效果图
通知中心
关键代码
import 'package:flutter/material.dart';
class ScrollStatusPage extends StatefulWidget {
@override
_ScrollStatusState createState() => new _ScrollStatusState();
}
class _ScrollStatusState extends State<ScrollStatusPage> {
String message = "";
_onStartScroll(ScrollMetrics metrics) {
setState(() {
message = "Scroll Start";
});
}
_onUpdateScroll(ScrollMetrics metrics) {
print(metrics.pixels);
setState(() {
message = "Scroll Update";
});
}
_onEndScroll(ScrollMetrics metrics) {
setState(() {
message = "Scroll End";
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("NotificationListener"),
),
body: Column(
children: <Widget>[
Container(
height: 50.0,
color: Colors.green,
child: Center(
child: Text(message),
),
),
Expanded(
child: NotificationListener<ScrollNotification>(
onNotification: (scrollNotification) {
if (scrollNotification is ScrollStartNotification) {
_onStartScroll(scrollNotification.metrics);
} else if (scrollNotification is ScrollUpdateNotification) {
_onUpdateScroll(scrollNotification.metrics);
} else if (scrollNotification is ScrollEndNotification) {
_onEndScroll(scrollNotification.metrics);
}
},
child: ListView.builder(
itemCount: 30,
itemBuilder: (context, index) {
return ListTile(title: Text("Index : $index"));
},
),
),
),
],
),
);
}
}
9.GestureDetector实现360展物
效果图
效果图
关键代码
import 'dart:async';
import 'package:flutter/material.dart';
class GestureDetectorPage extends StatefulWidget {
GestureDetectorPage({Key key, this.title}) : super(key: key);
final String title;
@override
_GestureDetectorPageState createState() => _GestureDetectorPageState();
}
class _GestureDetectorPageState extends State<GestureDetectorPage> {
int index = 1; // 第一张图片
int count = 72; // 图片总数
double initial = 0.0;
final int DIRECTION_ANTICLOCKWISE = 1; // 逆时针
final int DIRECTION_CLOCKWISE = -1; // 顺时针
int direction;
Timer _timer;
@override
void initState() {
super.initState();
direction = DIRECTION_CLOCKWISE;
_startTimer();
}
_startTimer() {
_timer = Timer.periodic(new Duration(milliseconds: 90), (timer) {
setState(() {});
if (direction == DIRECTION_ANTICLOCKWISE) {
if (index > 1) {
index--;
return;
}
// 重新回到第一张图
index = count;
} else if (direction == DIRECTION_CLOCKWISE) {
if (index < count) {
index++;
return;
}
// 重新回到第一张图
index = 1;
}
});
}
@override
Widget build(BuildContext context) {
var width = MediaQuery.of(context).size.width;
var height = width;
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
GestureDetector(
onTap: () => _cancelTimer(),
onPanStart: (e) => _cancelTimer(),
onPanUpdate: (e) => _onTouchImage(e),
// 在触屏结束之后,恢复自动旋转
onPanEnd: (e) => _startTimer(),
child: Image.asset(
'assets/images/product00${index}.png',
fit: BoxFit.cover,
width: width,
height: height,
// 该属性防止图片快速切换时白屏发生,在新图出前时保持旧的图
gaplessPlayback: true,
excludeFromSemantics: true,
),
)
],
),
),
);
}
void _onTouchImage(e) {
if (e.delta.dx < 0) {
direction = DIRECTION_CLOCKWISE;
}
if (e.delta.dx > 0) {
direction = DIRECTION_ANTICLOCKWISE;
}
setState(() {
index -= e.delta.dx.toInt();
});
// 防止取到不存在的图片报错
if (index < 1) index = 1;
if (index > count) index = count;
}
@override
void dispose() {
super.dispose();
_cancelTimer();
}
void _cancelTimer() {
_timer?.cancel();
}
}
网友评论