在这个系列中,我们将学习如何使用google的移动开发框架flutter创建一个电商应用。本文是flutter框架系列教程的第一部分,将学习如何安装Flutter开发环境并创建第一个Flutter应用,并学习Flutter应用开发中的核心概念,例如widget、状态等。
本系列教程包含如下四个部分,敬请期待:
- 如何从零构建flutter应用
- 如何在flutter中布局元素
- 如何在flutter中组织数据
- 如何在flutter中展示数据
1. 开发环境安装与Flutter项目创建
Flutter的开发文档相当出色,请参考官方文档先安装开发环境。
一旦开发环境安装好,我们可以创建一个新的测试项目。我倾向于使用android studio,因为它为flutter应用的开发提供了一个完备的集成开发环境。你需要在Android studio中安装一个Dard语言插件。
现在启动Android Studio,你会看到初始化Flutter项目的选项:
从配置列表中选择**Flutter Application **。
可以为你的第一个Flutter应用起一个酷炫的名字,不过如果你和我一样不善于起名,就用timer好了。
对话框的最后一步,会要求我们填写应用的包名:
接下来Flutter SDK就会为应用创建一个初始的目录结构,main.dart是应用执行的入口。
2. 编写并测试应用代码
在Flutter中,一切都是控件(widget)。Flutter应用中的图像、图标和文本都是widget。布局元素例如行、列、栅格等用来安排其他widget的位置、大小和对齐,而这些布局元素本身也是widget。
参考如下代码修改你的main.dart文件:
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Welcome to Flutter',
home: Scaffold(
appBar: AppBar(
title: Text('Welcome to Flutter'),
),
body: Center(
child: Text('Hello World'),
),
),
);
}
}
复制代码
现在启动Android模拟器:
注意widget的焦点,我们接下来将修改MaterialApp的内容。先看一下原始版本:
body: Center(
child: Text('Hello World'),
)
复制代码
Flutter中的布局元素(也是widget)可以根据其是否支持包含多个widget,而简单地归类为两种类型。例如,Container、Padding只能包含一个子widget,而Row、Column则可以包含多个。
现在我们在Row布局中引入三个文本widget:
body: Center(
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text('0'),
Text('0'),
Text('0'),
],
),
),
复制代码
现在看起来是这样:
在我们开始设置组件的样式之前,建议先创建一个新的widget来处理样式问题,以便遵循DRY(Don't Repeat Yoursel)原则。
将三个子widget用一个自定义widget(后面解释)替换。现在main.dart文件变成:
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Welcome to Flutter',
home: Scaffold(
appBar: AppBar(
title: Text('Timer'),
),
body: Center(
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
CustomTextContainer(),
CustomTextContainer(),
CustomTextContainer(),
],
),
),
),
);
}
}
class CustomTextContainer extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Text('00');
}
}
复制代码
我不是很擅长用户界面,但是我们还是尽力吧,加点背景色,留点空白:
class CustomTextContainer extends StatelessWidget {
CustomTextContainer({this.label, this.value});
final String label;
final String value;
@override
Widget build(BuildContext context) {
return Container(
margin: EdgeInsets.symmetric(horizontal: 5),
padding: EdgeInsets.all(20),
decoration: new BoxDecoration(
borderRadius: new BorderRadius.circular(10),
color: Colors.black87,
),
child: Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
Text(
'$value',
style: TextStyle(
color: Colors.white,
fontSize: 54,
fontWeight: FontWeight.bold,
),
),
Text(
'$label',
style: TextStyle(
color: Colors.white70,
),
)
],
),
);
}
}
复制代码
同时,在文本下面插入一个按钮widget,修改后的代码运行结果如下:
现在到了app最不可或缺的部分了:状态。状态将持有timer的当前值和运行标识。我 补充了一个TimerState类,它负责维护状态,同时构建widget树。
class Timer extends StatefulWidget {
@override
State<StatefulWidget> createState() {
return new TimerState();
}
}
class TimerState extends State<Timer> {
int secondsPassed = 0;
bool isActive = false;
@override
Widget build(BuildContext context) {
// Return Widget Tree
}
}
复制代码
按钮用来切换timer的运行或者停止:
RaisedButton(
child: Text(isActive ? 'STOP' : 'START'),
onPressed: () {
setState(() {
isActive = !isActive;
});
},
)
复制代码
Dart有个用于异步操作的优雅的模块。我们可以使用其Timer类来实现读秒。修改后的TimerAppState代码如下,注意我们已经重构Timer类并改名为TimerApp以避免与异步模块中的Timer类混淆:
class TimerAppState extends State<TimerApp> {
static const duration = const Duration(seconds:1);
int secondsPassed = 0;
bool isActive = false;
Timer timer;
void handleTick() {
if (isActive) {
setState(() {
secondsPassed = secondsPassed + 1;
});
}
}
@override
Widget build(BuildContext context) {
if (timer == null)
timer = Timer.periodic(duration, (Timer t) {
handleTick();
});
int seconds = secondsPassed % 60;
int minutes = secondsPassed ~/ 60;
int hours = secondsPassed ~/ (60*60);
return MaterialApp(...)
}
}
复制代码
好了,我们已经完成了第一个Flutter应用,完整的Dard代码可以在这里下载。
原文链接:【Flutter教程】从零构建电商应用(一)](blog.hubwiz.com/2018/12/11/…)
汇智网翻译整理,转载请标明出处。