learn-tech/专栏/Flutter入门教程/09校验结果与提示信息.md
2024-10-16 00:01:16 +08:00

156 lines
4.7 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

因收到Google相关通知网站将会择期关闭。相关通知内容
09 校验结果与提示信息
1. 需求中的状态数据分析
在上一篇中,已经准备好了数据和界面。本篇将介绍比较结果的校验,以及展示用户输入值和随机目标值的大小信息。点击确定时,可能的结果有 3 中,如下所示:
如下所示,是点击确定时不同情况下期望的界面效果;也就是说,界面的展现需要随着用户交互而变化。所以在当前需求之下,需要引入新的状态数据,用于控制界面的表现。
大了
小了
相等
这个状态数据将用于表示校验结果,该用什么类型呢?首先要明确一点:比较结果有三种情况: 大了、小了、相等 。其实只要某种数据类型包含三个值,都可以用于表示校验状态,只要逻辑正确即可,比如:
int 型:
0: 大了
1: 小了
2: 相等
String 型:
'big': 大了
'small': 小了
'equal': 相等
但如果用 int 或 String 表示,首先必须提前做出规定。而对于不了解规定的人,在阅读时会增加理解的难度。如果这种类似的规定场景在一个项目里经常出现,就是一个个雷点,迟早会爆炸。其实 bool 类型的出现,就是为了避免用 0 和 1 整数来表示真假,带来语义上的难以理解。
能且仅能是一种语法上的约束,可以在根源上杜绝一些可能发生的错误。那问一个问题,什么类型有且仅有 3 个值?很多人会说 枚举,这确实可以,不过稍显麻烦。这里想用 bool?来表示三态,它有如下三个值:
null: 相等
true: 大了
false: 小了
分析完后,现在 _GuessPageState 里定义为变量 _isBig 作为状态数据,控制校验结果。默认为 null
bool? _isBig;
2. 校验逻辑与状态数据的维护
校验逻辑算是比较简单的,对状态数据的维护可以称之为 业务逻辑,校验逻辑将在 _onCheck 回调中进行。上篇说过,这里可以得到目标值和输入值,输入值可以通过 int.tryParse 吧字符串转为整型。
有些小细节要注意一下:如果 _guessing 为 false ,表示游戏未开始;或输入的不是整数,此时应该不做响应,直接返回即可。
void _onCheck() {
print("=====Check:目标数值:$_value=====${_guessCtrl.text}============");
int? guessValue = int.tryParse(_guessCtrl.text);
// 游戏未开始,或者输入非整数,无视
if (!_guessing || guessValue == null) return;
//猜对了
if (guessValue == _value) {
setState(() {
_isBig = null;
_guessing = false;
});
return;
}
// 猜错了
setState(() {
_isBig = guessValue > _value;
});
}
如果猜对了,表示游戏结束,将 _guessing 置为 true、_isBig 置为 null ; 如果猜错了,通过 guessValue 和 _value 的比较结果,为 _isBig 赋值。这就是对状态数据的维护过程。
3. 状态数据与界面构建逻辑
状态数据以及维护完毕,下面来看一下最后一步:使用 _isBig 状态控制界面的呈现。从最终效果可以推断出_isBig 对界面的功效:
大了
小了
相等
背景的色框提示,只有在大了或小了时才会出现,也就是说当 _isBig != null 时才会出现,对应下面代码的 69 行 。
大了和小了是互斥的,不会同时出现,通过 Spacer 进行占位,大了时占下半;小了时占上半。
注: isBig! 是空安全的语法,如果一个可空对象 100% 确定非 null。可以通过 对象名! 表示 非空对象。 由于上面 if(_isBig) 才会走下方逻辑,所以使用处 100% 非空。
4.本章小结
到这里,猜数字简单版本就已经完成了。当前代码提交位置: guess_page.dart 你可以随机生成数字,在输入框中猜测数字,并校验猜测的值,给出提示。虽然是个小案例,但相比于计数器来说复杂了一些,额外维护了几个状态数据,界面布局上也更加复杂。是一个初学者进一步了解 Flutter 的好案例,把它吃透,会对你受益匪浅。
虽然现在可以完成猜数字需求,但是还有一点缺陷。比如当校验 小了, 下次校验还小时,由于 _isBig 的状态类没变,提示界面就没有任何变化(下左图)。如果用户的一个操作得不到反馈,体感上会觉得可能没点好;此时给予用户视觉上的反馈就会有比较好的体验,比如加一个动画效果(下左图)
无动画
有动画