手势
说明:
Flutter的手势系统分为两层,第一层是触摸原事件(指针),有相应的四种事件类型:
- PointerDownEvent:用户与屏幕接触产生了联系;
- PointerMoveEvent:手指已从屏幕上的一个位置移动到另一个位置;
- PointUpEvent:用户已停止接触屏幕;
- PointerCancelEvent:此指针的输入不再指向此应用程序。
第二层就是我们可以检测到的手势,主要分为三大类,包括轻击、拖动和缩放。
下面,我们来学习GestureDetector(进行手势检测)、Dismissible(实现滑动删除)
用GestureDetector进行手势检测
手势事件以及描述表:
事件名 | 描述 |
---|---|
onTapDown | 点击屏幕立即触发此方法 |
onTapUp | 手指离开屏幕 |
onTap | 点击屏幕 |
onTapCancel | 此次点击事件结束,onTapDown不会再产生点击事件 |
onDoubleTap | 用户快速连续两次在同一位置点击屏幕 |
onLongPress | 长时间保持与相同位置的屏幕接触 |
onVerticalDragStart | 与屏幕接触,可能会开始垂直移动 |
onVerticalDragUpdate | 与屏幕接触并垂直移动的指针在垂直方向上移动 |
onVerticalDragEnd | 之前与屏幕接触并垂直移动的指针不再与屏幕接触,并且在停留接触屏幕时以特定的速度移动垂直拖动 |
onHorizontalDragStart | 与屏幕接触,可能开始水平移动 |
onHorizontalDragUpdate | 与屏幕接触并水平移动的指针在水平方向上移动 |
onHorizontalDragEnd | 先前与屏幕接触并且水平移动的指针不再与屏幕接触,并且当它停止接触屏幕时以特定速度移动水平拖动 |
例子:制作一个自定义的按钮,当点击时显示文字“你已按下”
代码:
main.dart
import 'package:flutter/material.dart';
import 'package:route_page/route/page_jumps.dart';
import 'package:route_page/route/return_message.dart';
import 'package:route_page/route/send_message.dart';
import 'gesture/test_button.dart';
void main() {
runApp(
// new MaterialApp(
// title: "导航页面示例",
// home: new FirstScreen(),
// )
// new MaterialApp(
// title: "传递数据示例",
// home: new ProductList(
// products:
// new List.generate(20, (i) => new Product('商品 $i', "这是一个商品详情 $i"))),
// )
// new MaterialApp(
// title: '页面跳转发、返回数据',
// home: new FirstPage(),
// )
new MaterialApp(
title: '页面跳转发、返回数据',
home: new MyButton(),
)
);
}
test_button.dart
import 'package:flutter/material.dart';
class MyButton extends StatelessWidget{
@override
Widget build(BuildContext context) {
// TODO: implement build
return Scaffold(
appBar: AppBar(
title: Text("按下处理Demo"),
),
// 注意:在同一个函数中实际创建了Scaffold时,该build函数的context参数不能用于查找Scaffold
// (因为它在小部件树返回的小部件上方)。在这种情况下,可以使用带有Builder来提供一个行的作用域,该作用域具有位于Scaffold下方的BuildContext.
body: Builder(
builder: (BuildContext context){
return new Center(
// 一定要把被触摸的组件放在GestureDetector中
child: GestureDetector(
onTap: (){
// 底部信息揭示
final snackBar = new SnackBar(content: new Text("你已按下按钮"));
Scaffold.of(context).showSnackBar(snackBar);
},
// 容器接收触摸动作
child: new Container(
child: new Text("测试按钮"),
padding: EdgeInsets.all(12.0),
decoration: BoxDecoration(
color: Theme.of(context).buttonColor,
borderRadius: new BorderRadius.circular(10.0)
),
),
),
);
},
)
);
}
}
用Dismissible实现滑动删除
-
Dismissible组件属性及描述表
属性名 类型 说明 onDismissed DismissDirectionCallback 当包裹的组件消失后回调的函数 movementDuration Duration 定义组件消息的时长 onResize VoidCallback 组件大小改变时回调的函数 resizeDuration Duration 组件大小改变时长 child Widget 组件包裹的子元素,即被隐藏的对像 -
例子:实现滑动列表中的某一项数据,就可以删除的效果
main.dart
iimport 'package:flutter/material.dart'; import 'package:route_page/route/page_jumps.dart'; import 'package:route_page/route/return_message.dart'; import 'package:route_page/route/send_message.dart'; import 'gesture/dismissible.dart'; import 'gesture/test_button.dart'; void main() { runApp( // new MaterialApp( // title: "导航页面示例", // home: new FirstScreen(), // ) // new MaterialApp( // title: "传递数据示例", // home: new ProductList( // products: // new List.generate(20, (i) => new Product('商品 $i', "这是一个商品详情 $i"))), // ) // new MaterialApp( // title: '页面跳转发、返回数据', // home: new FirstPage(), // ) // new MaterialApp( // title: '页面跳转发、返回数据', // home: new MyButton(), // ) new MaterialApp( title: ' 滑动删除示例', home: new MyApp(), ) ); }
dismissible.dart
import 'package:flutter/material.dart'; class MyApp extends StatelessWidget{ List<String> items = new List<String>.generate(30, (i) => "列表项 ${i+1}"); @override Widget build(BuildContext context) { // TODO: implement build return Scaffold( appBar: AppBar( title: Text("滑动删除示例"), ), // 使用ListView.builder生成列表,将列表中的每一项子项(ListTile)包装在Dismissible中; // 在onDismissed执行真正的删除操作 body: new ListView.builder( itemCount: items.length,//决定itemBuilder回调函数的次数 itemBuilder: (context,index){ final item = items[index]; // 对需要实现滑动清除的Widget包装在child中 return new Dismissible( key: new Key(item),//key是widget的唯一标示,因为有了key,widget tree才知道我们删除了什么widget // 可以被删除的组件 child: new ListTile(title: new Text('$item'),), // 完成清除后,进行的操作 onDismissed: (direction){ // 删除后刷新列表,已到达真正的删除 items.removeAt(index); Scaffold.of(context).showSnackBar(new SnackBar(content: new Text("$item 被删除来"))); }, ); }, ) ); } }