目录
- 配置环境
- 运行官方演示项目
- 编写一个列表应用
- 混合开发 iOS版
前言
Flutter应用一切正常,下面开始写代码,找到官方教程按步骤敲就好了。
其实这些代码我昨天就敲过了,不过有些地方没看明白,写这篇教程的时候也顺便复习一下。
第一步:替换演示代码
替换工程目录下 lib/main.dart
文件的代码
import 'package:flutter/material.dart';
void main() => runApp(new MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return new MaterialApp(
title: 'Welcome to Flutter',
home: new Scaffold(
appBar: new AppBar(
title: new Text('Welcome to Flutter'),
),
body: new Center(
child: new Text('Hello World'),
),
),
);
}
}
简要分析
material.dart
是视觉设计相关的包(by: 官方教程)MyApp
继承自StatelessWidget
,说明它的属性变化不会重新渲染页面Scaffold
类似iOS的ViewController
,里面提供了默认的导航栏appBar
和内容容器body
第二步: 使用外部包(package)
这一步很多框架都会用到,作为程序员都不会陌生
找到pubspec.yaml
文件,在dependencies:
下方添加我们要引用的包english_words: ^3.1.0
,这个包在本章中仅用来示范引用包文件。
...
dependencies:
flutter:
sdk: flutter
# The following adds the Cupertino Icons font to your application.
# Use with the CupertinoIcons class for iOS style icons.
cupertino_icons: ^0.1.2
english_words: ^3.1.0
...
在VS Code中,如果安装了Flutter插件,在保存pubspec.yaml
文件时,会自动下载并安装对应的包,无需手动执行,随后可以在代码中引用对应的包。
输入关键字后会有联想内容提示。
不过,不知道是VS Code还是Dart插件的问题,这个联想不是很智能,一旦输入过程出现中断,联想就不会再出现了。
第三步:创建一个可以滚动的列表
从这里开始就和官方教程不一样了,后面是偷懒的简化版本
首先,建立在模块化编程的思维基础上,我们应该新建一个文件TextListScaffoldWidget.dart
用来编写列表代码。
import 'package:flutter/material.dart';
class TextListScaffoldState extends State {
final _textTiles = List(10);
@override
Widget build(BuildContext context) {
//生成列表卡片
for (var i = 0; i < _textTiles.length; i++) {
final text = new Text(i.toString());
final tile = new ListTile(title: text,);
_textTiles[i] = tile;
}
//生成主要页面
return new Scaffold(
appBar: new AppBar(
title: new Text('Text List'),
),
//生成列表
body: new ListView(children: _textTiles),
);
}
}
class TextListScaffoldWidget extends StatefulWidget {
@override
State createState() {
return TextListScaffoldState();
}
}
之后,我们需要在main.dart
中引用该文件,并将TextListScaffoldWidget
设置为主页
import 'package:flutter/material.dart';
import 'TextListScaffoldWidget.dart';
void main() => runApp(new MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return new MaterialApp(
title: 'Welcome to Flutter',
home: new TextListScaffoldWidget()
);
}
}
保存代码之后可以在连接的设备上看到热重载之后的界面
简要分析
- 代码主要内容是先生成一个长度为10的数组,向内填充
ListTile
,随后用他们来创建ListView
,最后把他们塞到Scaffold
的body
里面ListTile
类似iOS中的Cell
,ListView
类似iOS中的TableView
- 我习惯的文件命名规范是
业务+功能+类型
对应的是TextList+Scaffold+Widget
TextListScaffoldWidget
继承自StatefulWidget
,与StatelessWidget不同,它的属性State
变化会重新渲染页面
第四步:添加点击功能
这一步主要是展示StatefulWidget
对State
变化的响应,内容很简单,点击Tile
的时候,在title后面添加后缀“_s”
首先,在tile
初始化时添加onTap
点击事件,点击事件中使用setState
来通知页面状态改变,需要重新渲染
然后,由于ListView
的构造方法不响应State
,所以要把ListView
的初始化方式换成ListView.builder()
...
class TextListScaffoldState extends State {
final _textTiles = List(10);
var _selectedIndex = -1;
@override
Widget build(BuildContext context) {
for (var i = 0; i < _textTiles.length; i++) {
final isSelected = _selectedIndex == i;
final suffix = isSelected ? '_s' : '';
final text = new Text(i.toString() + suffix);
//添加点击事件
final tile = new ListTile(
title: text,
onTap: () {
setState(() {
_selectedIndex = i;
});
},
);
_textTiles[i] = tile;
}
return new Scaffold(
appBar: new AppBar(
title: new Text('Text List'),
),
//更换初始化方式
body: new ListView.builder(
itemBuilder: (context, i) {
if (i < _textTiles.length) {
return _textTiles[i];
}
return null;
},
),
);
}
}
...
保存代码,之后列表变为可点击模式,点击时会有Flutter默认的波纹效果,被点击的卡片会显示“_s”后缀
简要分析
setState
和属性的修改没有直接关联,完全可以先修改属性,然后执行该方法,效果相同。代码如下onTap: () { _selectedIndex = i; setState(() { }); },
第四步:添加跳转功能
为了省事,我选择套娃。点击卡片的时候跳转一个新的TextListScaffold
替换tile
初始化方法里的onTap
的实现内容就可以了
...
final tile = new ListTile(
title: text,
onTap: () {
Navigator.of(context).push(
new MaterialPageRoute(
builder: (context) {
return new TextListScaffoldWidget();
}
)
);
},
);
_textTiles[i] = tile;
}
...
保存代码,开始套娃!
简要分析
Navigator.of(context)
是导航管理器,应该是个单例,他会显示最顶层的路由内容。用MaterialPageRoute
创建一个新页面的路由,把路由推入导航管理器的栈中,就会显示新页面。- 看了下Flutter的接口,好像没有类似iOS中
present
行为的控制器展示,尝试了一下用导航管理器做模态视图,感觉有些麻烦。(参考Flutter Ui 实验室(一)模态弹窗)
参考文章: statelessWidget和statefulWidget简介
后记
简单的跟着教程写了两遍,对基础框架稍微熟悉了一点。感觉Flutter上手还是很快的,如果是做小规模独立开发或者简单的应用原型的话,应该是个非常合适的UI框架。