安装、调试(1)
现在,点击 Run,把我们的第一个 Flutter 应用跑起来吧。没有意外的话,你会看到下面这个页面:
如果你遇到了什么困难,可以查看 tag first_app_step1 的代码:
git clone https://github.com/Jekton/flutter_demo.git
cd flutter_demo
git checkout first_app_step1
由于是第一次写 Flutter 应用,我们对上面的代码是否能够按照预期执行还不是那么有信心,所以我们先打个 log 确认一下,点击按钮后是不是真的会执行 onPress
。
打 log 可以使用 Dart 提供的 print
,但在日志比较多的时候,print
的输出可能会被 Android 丢弃,这个时候 debugPrint
会是更好的选择。对应的日志信息可以在 Dart Console 里查看(View -> Tool Windows -> Run 或者 Mac 上使用 Command+4 打开)。
void _onPressed() {
debugPrint(‘_onPressed’);
}
保存后(会自动 Hot Reload),我们再次点击按钮,在我的设备上,打印出了下面这样的信息:
I/flutter (11297): _onPressed
V/AudioManager(11297): playSoundEffect effectType: 0
V/AudioManager(11297): querySoundEffectsEnabled…
这里的第一行,就是我们打的。现在我们有足够的自信说,点击按钮后,会执行 _onPressed
方法了。
编写代码(2)
软件开发通常是一个螺旋式上升的过程,不可能通过一次编码、调试就完成。现在,我们开始第二轮迭代。
接下来要做的,便是在 _onPressed
里面弹一个框:
// context 这里使用的是 MyApp.build 的参数
void _onPressed(BuildContext context) {
debugPrint('onPressed’);
showDialog(
context: context,
builder: () {
return AlertDialog(
content: Text(‘AlertDialog’),
);
}
);
}
遗憾的是,这一次并不那么顺利。Dialog 没有弹出来,而且报了下面这问题:
I/flutter (11297): Navigator operation requested with a context that does not include a Navigator.
I/flutter (11297): The context used to push or pop routes from the Navigator must be that of a widget that is a
I/flutter (11297): descendant of a Navigator widget.
原因在于,stateless 的 widget
只能用于显示信息,不能有其他动作。所以,该让 StatefulWidget
上场了。
class RollingButton extends StatefulWidget {
// StatefulWidget 需要实