简介
之前我们介绍了GestureDetector的定义和其提供的一些基本的方法,GestureDetector的好处就是可以把任何一个widget都赋予类似button的功能。
今天将会通过几个具体的例子来讲解一下GestureDetector的具体使用。
一般情况下,我们的普通widget,比如文本是不能进行交互的,但是如果将其用GestureDetector进行包装之后,就可以将其伪装成为一个button。
比如我们有这样一个伪装成button的Container:
Container(
padding: const EdgeInsets.all(12.0),
decoration: BoxDecoration(
color: Colors.green,
borderRadius: BorderRadius.circular(8.0),
),
child: const Text('My Button'),
)
这个Container的本质是一个Text,这个Container本身是没有交互功能的,那么如何对其添加交互功能呢?
最简单的办法就是将其使用GestureDetector包装起来,如下所示:
GestureDetector(
// The custom button
child: Container(
padding: const EdgeInsets.all(12.0),
decoration: BoxDecoration(
color: Colors.green,
borderRadius: BorderRadius.circular(8.0),
),
child: const Text('My Button'),
),
)
接下来我们还要为其添加对应的手势,这里我们添加一个onTap方法,
GestureDetector(
onTap: ()=> showDialog<string>(
context: context,
builder: (BuildContext context) => AlertDialog(
title: const Text('基本手势'),
content: const Text('这是基本的手势,你学会了吗?'),
actions: <widget>[
TextButton(
onPressed: () => Navigator.pop(context, 'Cancel'),
child: const Text('Cancel'),
),
TextButton(
onPressed: () => Navigator.pop(context, 'OK'),
child: const Text('OK'),
),
],
),
),
...
</widget></string>
这里onTap会调用一个showDialog来弹出一个对话框,运行之后结果如下:

会动的组件
在上面的例子中,我们用手去tap按钮是没有互动效果的,也就是说按钮是不会变化的。
那么有没有可能模拟手指的按压效果呢?
答案是肯定的,flutter为我们提供了一个InkWell组件,这样手指按压下组件会产生波纹的效果。
那么InkWell和GestureDetector有什么联系呢?
InkWell和GestureDetector很类似,都提供了对手势的支持。
在InkWell中提供了多种GestureTapCallback接口,用接收手势的回调,非常的方便。
在使用上,InkWell和GestureDetector也很类似,我们可以完全照搬GestureDetector的用法。
还是上面的例子,我们可以将GestureDetector替换成为InkWell,如下所示:
Widget build(BuildContext context) {
return InkWell(
onTap: () {
ScaffoldMessenger.of(context).showSnackBar(const SnackBar(
content: Text('Tap'),
));
},
child: const Padding(
padding: EdgeInsets.all(12.0),
child: Text('Flat Button'),
),
);
}
这里,为了更好的观察手势按压之后的效果,这里onTap选择展示一个flutter自带的SnackBar。
可删除的组件
在app中的手势应用上,有一个比较常见的用法就是在list列表中,向左滑动一个item,会出现删除的按钮,这种滑动删除的效果,如何在flutter中实现呢?
flutter提供了一个Dismissible的组件来实现这个效果。
我们先来看下Dismissible的定义:
class Dismissible extends StatefulWidget {
const Dismissible({
required Key key,
required this.child,
this.background,
this.secondaryBackground,
this.confirmDismiss,
this.onResize,
this.onUpdate,
this.onDismissed,
this.direction = DismissDirection.horizontal,
this.resizeDuration = const Duration(milliseconds: 300),
this.dismissThresholds = const <dismissdirection, double>{},
this.movementDuration = const Duration(milliseconds: 200),
this.crossAxisEndOffset = 0.0,
this.dragStartBehavior = DragStartBehavior.start,
this.behavior = HitTestBehavior.opaque,
}) : assert(key != null),
assert(secondaryBackground == null || background != null),
assert(dragStartBehavior != null),
super(key: key);
</dismissdirection,>
可以看到Dismissible是一个StatefulWidget,它有两个必须的参数分别是key和child。
key用来标记要删除item的id,child是可以滑动删除的组件。
为了演示方便,我们使用ListView来展示如何使用Dismissible。
首先我们构建一个items的list,里面包含了每个item要展示的内容:
final items = List<string>.generate(10, (i) => '动物 ${i + 1}');
</string>
然后使用ListView的builder方法来构建items。并且将每个items封装到Dismissible中去:
body: ListView.builder(
itemCount: items.length,
itemBuilder: (context, index) {
final item = items[index];
return Dismissible(
key: Key(item),
onDismissed: (direction) {
setState(() {
items.removeAt(index);
});
ScaffoldMessenger.of(context)
.showSnackBar(SnackBar(content: Text('$item 被删除了')));
},
child: ListTile(
title: Text(item),
),
);
},
)
这里Dismissible的child是ListTile组件,里面的具体内容就是Text。
现在Dismissible实际上就可以工作了,当你滑动ListTile的时候,对应的item就会被删除。
为了明显起见,我们可以给Dismissible添加一个background属性,这样滑动删除的时候就有了一个背景颜色:
background: Container(color: Colors.red),
另外,Dismissible还有一个confirmDismiss属性,可以用来判断是否真的要滑动删除,比如我们只允许从右到左滑动删除,那么可以这样做:
Dismissible(
...
confirmDismiss:confirmResult,
...
)
Future<bool> confirmResult(DismissDirection direction) async {
if(direction == DismissDirection.endToStart){
return true;
}
return false;
}
</bool>
这里的confirmResult是一个异步函数,它接收一个DismissDirection的参数,这个参数表示的是滑动删除的方向,我们可以通过这个方向来判断是否真正的进行删除操作。
总结
以上就是日常手势的基本使用了,我们可以通过GestureDetector,InkWell和Dismissible来和手势进行结合来实现相应的功能。
本文的例子:https://github.com/ddean2009/learn-flutter.git
更多内容请参考 www.flydean.com
*[En]*
**
欢迎关注我的公众号:「程序那些事」,懂技术,更懂你!
Original: https://www.cnblogs.com/flydean/p/16992968.html
Author: flydean
Title: flutter系列之:移动端手势的具体使用
相关阅读
Title: SPSS中系统聚类操作案例
示例:
一位啤酒酿造商想要了解目前的啤酒市场,并判断最受欢迎的啤酒品牌,收集各种啤酒的价格、卡路里、钠含量、酒精含量等数据。采用系统聚类法对数据进行分析,得出以下结果:
[En]
A brewer wants to know about the current beer market and judge the most popular beer brands, collecting data on a variety of beer in terms of price, calorie, sodium content, alcohol content and so on. The system clustering method is used to analyze the data, and the following results are given:
(1)所有样本的归类情况表(群集成员表);
(2)所有样本的树状图;
(3)简要分析聚类结果。(酒精含量较高的啤酒酒质较好,国际上公认12°以上的啤酒为高级啤酒,酒精含量5%左右;低”钠”含量的食物较健康)。
主要操作步骤如下:

(1)将变量移入 变量框 中。将标志变量 啤酒名 移入 个案标记依据框 中;
在 分群 栏中选择 个案 单选按钮,即对样品进行聚类(若选择 变量,则对变量进行聚类)。在 输出 栏中选择 统计量 和 图复选框,这样在结果输出窗口中可以同时得到聚类结果统计量和统计图。

(2)点击 统计量 按钮,设置在结果输出窗口中给出的聚类分析统计量。在 聚类成员 中, 方案范围2—4(此数值不固定,可根据实际情况而定),这样在结果输出窗口中可以得到分别分成2、3、4类的聚类结果;点击 继续 按钮;

(3)点击 绘制 按钮,设置结果输出窗口中给出的聚类分析统计图。选中 树状图 复选框和 冰柱 栏中的 无 单选按钮,即只给出聚类树形图,而不给出冰柱图。单击 继续 按钮,返回主界面;
树形图可以直观地看到整个聚类过程和结果,是观察和了解聚类结果的重要图表,一般选择它;冰点图也是一种查看聚类结果的图表,但在适用范围和可理解性方面不如树形图表,所以这里不选择它。
[En]
The tree diagram can directly see the whole clustering process and results, which is an important graph to observe and understand the clustering results, and generally choose it; icicle chart is also a kind of graph to view the clustering results, but it is worse than the tree diagram in terms of application scope and understandability, so it is not selected here.

(4)点击 方法 按钮,设置系统聚类的方法选项。 聚类方法 下拉列表用于指定聚类的方法,包括组间连接、组内连接、Ward法等;不同的聚类方法结果不一定完全相同,一般只是大致相似。如果有很大的差异,则应该仔细考查,找到问题所在;另外,可将聚类结果与实际问题对照,看哪一个结果更符合经验;这里沿用系统默认选项;
度量标准 用于选择对距离和相似性的测度方法。一般而言对每一类变量类型使用其默认方法即可;
转换值 和 转换 度量 用于选择对原始数据进行标准化的方法。当进行聚类的变量之间数量级相差比较大的时候,往往要根据数据的实际情况选择相应的标准化方法,这里将全部数据标准化为 Z得分。右侧的 转换 变量 还可以设置进一步的变换方法,可以为 先取绝对值再变换、变换后更改正负号、或者先将取值范围变为0-1再进行变换。一般来说不需要使用这些选项。单击 继续,返回主界面。
(5)点击 确定 按钮,得到系统聚类分析结果。
主要结果如下:
(1)所有样本的归类情况表(群集成员表);

“群集成员”表格是聚类个数为2—4时的类成员表;在数据编辑窗口生成了同样的内容,即3个变量,保存聚类个数分别为2、3、4时的分类结果,如下所示。

(2)所有样本的树状图;
图的左侧表示聚集的对象,而对象的合并则以线连接的方式表示。在本例中,每个啤酒都列在结果的最左端,而结果的上端给出了类别之间的相对距离。
[En]
The left side of the graph represents the clustered objects, while the merging of objects is expressed by the way of line connection. In this example, each beer is listed at the leftmost end of the result, while the upper end of the result gives the relative distance between categories.

(3)简要分析聚类结果。(酒精含量较高的啤酒酒质较好,国际上公认12°以上的啤酒为高级啤酒,酒精含量5%左右;低”钠”含量的食物较健康)
根据保存的分类结果,比较各类啤酒的价格、酒精含量、钠含量和卡路里,分析各类啤酒的质量;或描述性分析(简单直观地研究不同类别之间的差异,从平均值、标准差等),进一步分析聚类结果。
[En]
According to the preserved classification results, the price, alcohol content, sodium content and calorie of all kinds of beer are compared, and the quality of all kinds of beer is analyzed; or descriptive analysis (simple and intuitive study of the differences between different categories from the mean, standard deviation, etc.), further analysis of the clustering results.
描述性分析:





拖动调整3个描述量的位置如下所致:

关闭窗口即得到:系统聚类的PLAP立方体(以分三类为例,其他类别分析类似)

由各类均值看出,第一类售价较高,酒精含量高且接近5%,钠含量较低(比第3类略高);第三类价格最低,酒精含量也远低于一、二类;第二类售价和热量适中,酒精含量较高,且此类聚类数最多(14个),该类啤酒市场占有额较大。综合判断,第一类啤酒价格高、品质好,第二类最受市场青睐,第三类低能量、低度数,市场份额小。
Original: https://blog.csdn.net/m0_46582608/article/details/125748250
Author: 努力学习GIS1
Title: SPSS中系统聚类操作案例
原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/272967/
转载文章受原作者版权保护。转载请注明原作者出处!