对于手势的运用
指针表示用户与设备屏幕交互的原始数据。有四种类型的指针事件
PointerDownEvent指针触摸屏幕上的特定位置
PointerMoveEvent指针从屏幕上的一个位置移动到另一个位置
PointerUpEvent指针停止触摸屏幕
PointerCancelEvent指针的输入事件不再针对此应用程序(事件取消)
Widget build(BuildContext context) {
return new GestureDetector(
onTap: _handleTap,
child: new Container(
child: new Center(
child: new Text(
_active ? 'Active' : 'Inactive',
style: new TextStyle(fontSize: 32.0, color: Colors.white),
),
),
width: 200.0,
height: 200.0,
decoration: new BoxDecoration(
color: _active ? Colors.lightGreen[700] : Colors.grey[600],
),
),
);
}
}
当按下指针时,框架将在应用程序上执行_点击测试_,以确定指针与屏幕相交的位置存在哪些小部件。然后,指针按下事件(以及该指针的后续事件)被分发到_命中测试_找到的最里面的小部件。从那里,这些事件将在小部件树中弹出。这些事件将从最里面的小部件分发到小部件根路径上的所有小部件。没有取消或停止冒泡过程的机制。
要直接从窗口小部件层侦听指针事件,请使用侦听器窗口小部件。然而,一般来说,考虑使用手势(如下所述)。要直接从小部件层侦听指针事件,可以使用Listenerwidgets。
单独指针
手势表示可以从多个单独指针事件(甚至多个单独的指针)中识别的语义动作(如敲击、拖动和缩放)。一个完整的手势可以调度多个事件,对应于手势的生命周期(例如,拖动开始、拖动更新和拖动结束):
class ParentWidget extends StatefulWidget {
@override
_ParentWidgetState createState() => new _ParentWidgetState();
}
class _ParentWidgetState extends State<ParentWidget> {
bool _active = false;
void _handleTapboxChanged(bool newValue) {
setState(() {
_active = newValue;
});
}
@override
Widget build(BuildContext context) {
return new Container(
child: new TapboxC(
active: _active,
onChanged: _handleTapboxChanged,
),
);
}
}
TaponTapDown指针已在特定位置与屏幕接触onTapUp指针停止在特定位置接触屏幕onTap tap事件触发onTapCancel之前由指针触发的onTapDown不会触发tap事件
双击DoubleTap可在同一位置连续两次快速点击屏幕
长按onLongPress指针可在同一位置长时间与屏幕保持接触
垂直拖动onVerticalDragStart指针已接触屏幕,并可能开始垂直移动。onVerticalDragUpdate指针已与屏幕接触并垂直移动OnVerticalDragEnd先前与屏幕接触且垂直移动的指针不再与屏幕接触,并在停止触摸屏幕时以特定速度移动
水平拖动onHorizontalDragStart指针已触摸屏幕,并可能开始水平移动onHorizontalDragUpdate指针接触屏幕并已水平移动onHorizontalDragEnd指针(以前接触屏幕并水平移动)不再接触屏幕,并在停止触摸屏幕时以特定速度移动
要从控件层监视手势,请使用手势检测器
class _MyHomePageState extends State<MyHomePage> {
@override
Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(
title: new Text(widget.title),
),
body: new Center(
child: new Text('Hello World', style: new TextStyle(fontSize: 32.0)),
),
);
}
}
如果使用“材质组件”,大多数小部件都会响应轻敲或手势。例如,IconButton和FlatButton响应按下(轻击),ListView响应滑动事件以触发滚动。如果不使用这些小部件,但希望在单击时具有“泼墨”效果,则可以使用InkWell。
消歧
在屏幕上的指定位置可能有多个手势检测器。当指针事件流通过并试图识别特定手势时,所有这些手势检测器都会监听指针事件流。手势检测器小部件确定它是哪个手势。
当屏幕上有多个给定指针的手势识别器时,框架通过向每个识别器添加“手势竞争场”来确定所需的手势。“手势比赛场”使用以下规则来确定哪个手势获胜
在任何时候,识别器都可以宣布失败并离开“手势比赛场”。如果“比赛场地”中只剩下一个标识符,则该标识符为获胜者
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
//...
Widget buttonSection = new Container(
child: new Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
buildButtonColumn(Icons.call, 'CALL'),
buildButtonColumn(Icons.near_me, 'ROUTE'),
buildButtonColumn(Icons.share, 'SHARE'),
],
),
);
//...
}
在任何时候,识别器都可以宣布胜利,这将导致胜利,而所有剩余的识别器都将失败
例如,当消除水平和垂直拖动的歧义时,两个识别器在接收到指针向下事件时进入“手势竞争场”。识别器观察指针移动事件。如果用户将指针水平移动超过一定数量的逻辑像素,则水平识别器将宣布胜利,手势将被解释为水平拖动。类似地,如果用户垂直移动超过一定数量的逻辑像素,则垂直识别器将宣布获胜。
当仅水平(或垂直)拖动识别器时,“手势竞争场”是有益的。在这种情况下,“手势竞争领域”中只有一个识别器,水平拖动将立即被识别,这意味着第一个水平移动的像素可以被视为拖动,用户不需要等待进一步的手势消歧。
依赖包中的字体
如果包中定义的字体在内部使用,则在创建文本样式时还应指定包参数,如上面的示例所示。
包还可以提供字体文件,而无需输入pubspec Yaml。这些文件应位于包的lib/文件夹中。字体文件不会自动绑定到应用程序,应用程序可以在声明字体时选择性地使用这些字体。假设a_包中有一个包:
flutter:
fonts:
- family: Raleway
fonts:
- asset: assets/fonts/Raleway-Regular.ttf
- asset: packages/my_package/fonts/Raleway-Medium.ttf
weight: 500
family是字体的名称。可以在TextStyle的fontFamily属性中使用它
资产相对于pubspec yaml文件的路径这些文件包含字体中的字形轮廓。构建应用程序时,这些文件将包含在应用程序的资产包中。
可以设置字体的粗细、倾斜和其他样式
weight属性指定字体的粗细。值范围是100到900(100的倍数)的整数。这些值对应于FontWeight,可用于TextStyle的FontWeight属性
样式指定字体是斜体还是普通字体。相应的值为斜体和普通值。这些值对应于fontStyle可用于TextStyle的fontStyle TextStyle属性
import 'package:flutter/material.dart';
const String words1 = "Almost before we knew it, we had left the ground.";
const String words2 = "A shining crescent far beneath the flying vessel.";
const String words3 = "A red flair silhouetted the jagged edge of a wing.";
const String words4 = "Mist enveloped the ship three hours out from port.";
void main() {
runApp(new MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return new MaterialApp(
title: 'Flutter Fonts',
theme: new ThemeData(
primarySwatch: Colors.blue,
),
home: new FontsPage(),
);
}
}
在Flutter应用程序中使用字体需要两个步骤。首先在pubspec.yaml中声明它们,以确保它们包含在应用程序中。