创建第一个Flutter App
本章将引导您创建一个Flutter App。如果您熟悉面向对象编程和基本编程概念(如变量、循环和条件判断),即使没有Dart或移动开发经验,也能轻松完成。
应用概述
您将为一个初创公司实现一个简单的移动应用,主要功能是推荐公司名称。用户可以点击选择或取消名称,保存最喜欢的选项。应用每次生成10个名称,并在用户滚动时持续产生新名称。通过点击导航栏的列表图标,用户可以进入新页面查看已保存的名称。
学习目标
- Flutter应用的基本结构
- 查找并使用包来扩展功能
- 使用热加载加快开发周期
- 实现有状态组件(Stateful Widget)
- 创建无限滚动的懒加载列表
- 创建并路由到第二个屏幕
- 使用应用主题修改外观
环境要求
- Flutter SDK(v0.1.4或更高版本),包含Flutter引擎、框架、组件、工具和Dart SDK。
- Android Studio(也可使用命令行工具)。
- IDE插件:在IDE中安装Flutter和Dart插件。
步骤详解
Step 1:创建Flutter App
首先,创建一个简单的Flutter应用。您可以使用IDE模板或通过命令行创建工程,工程名称可自定义(如flutter_app)。本节主要编辑lib/main.dart文件。
替换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'),
),
),
);
}
}
运行应用后,界面中央将显示“Hello World”文本。
代码解析:
- 应用继承
StatelessWidget,使应用本身成为一个组件。 MaterialApp使用Material设计标准,Scaffold提供默认的appbar、标题和body。build()方法描述如何展示组件,这里使用Center组件将文本居中显示。
Step 2:使用外部包
接下来,使用english_words包来生成常见英文单词。在pubspec.yaml文件的依赖部分添加:
dependencies:
flutter:
sdk: flutter
english_words: ^3.1.0
运行flutter pub get获取包。然后在lib/main.dart中导入并使用该包:
import 'package:flutter/material.dart';
import 'package:english_words/english_words.dart';
void main() => runApp(new MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
final wordPair = new WordPair.random();
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(wordPair.asPascalCase),
),
),
);
}
}
使用热加载更新应用,每次都会显示一个随机的大驼峰格式单词对。
Step 3:添加有状态组件
无状态组件不可变,而有状态组件(Stateful Widget)在生命周期中可改变状态。创建RandomWords组件及其状态类RandomWordsState。
在main.dart文件末尾添加:
class RandomWords extends StatefulWidget {
@override
createState() => new RandomWordsState();
}
class RandomWordsState extends State<RandomWords> {
@override
Widget build(BuildContext context) {
final wordPair = new WordPair.random();
return new Text(wordPair.asPascalCase);
}
}
更新MyApp的build方法,将body中的Text替换为RandomWords:
body: new Center(
child: new RandomWords(),
),
重启应用后,效果与之前相同,但已使用有状态组件。
Step 4:创建无限滚动列表
扩展RandomWordsState类以展示无限滚动的列表。添加私有变量_suggestions保存单词对列表和_biggerFont定义字体大小:
class RandomWordsState extends State<RandomWords> {
final _suggestions = <WordPair>[];
final _biggerFont = const TextStyle(fontSize: 18.0);
// ... 其他代码
}
添加_buildSuggestions()方法生成列表,使用ListView.builder进行懒加载:
Widget _buildSuggestions() {
return new ListView.builder(
padding: const EdgeInsets.all(16.0),
itemBuilder: (context, i) {
if (i.isOdd) return new Divider();
final index = i ~/ 2;
if (index >= _suggestions.length) {
_suggestions.addAll(generateWordPairs().take(10));
}
return _buildRow(_suggestions[index]);
}
);
}
添加_buildRow()方法显示每行内容:
Widget _buildRow(WordPair pair) {
return new ListTile(
title: new Text(
pair.asPascalCase,
style: _biggerFont,
),
);
}
更新build()方法返回包含AppBar和列表的Scaffold:
@override
Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(
title: new Text('Startup Name Generator'),
),
body: _buildSuggestions(),
);
}
重启应用后,将看到无限滚动的单词对列表。
Step 5:添加交互
为用户收藏功能添加交互。在RandomWordsState中添加_saved集合保存收藏的单词对:
final _saved = new Set<WordPair>();
更新_buildRow()方法,添加心形图标和点击事件:
Widget _buildRow(WordPair pair) {
final alreadySaved = _saved.contains(pair);
return new ListTile(
title: new Text(
pair.asPascalCase,
style: _biggerFont,
),
trailing: new Icon(
alreadySaved ? Icons.favorite : Icons.favorite_border,
color: alreadySaved ? Colors.red : null,
),
onTap: () {
setState(() {
if (alreadySaved) {
_saved.remove(pair);
} else {
_saved.add(pair);
}
});
},
);
}
运行应用后,点击每行可收藏或取消收藏,心形图标颜色会相应变化。
Step 6:跳转到另一个屏幕
添加新屏幕显示收藏的单词对。在RandomWordsState的build方法中,为AppBar添加列表图标按钮:
actions: <Widget>[
new IconButton(icon: new Icon(Icons.list), onPressed: _pushSaved),
],
定义_pushSaved()方法,导航到新页面:
void _pushSaved() {
Navigator.of(context).push(
new MaterialPageRoute(
builder: (context) {
final tiles = _saved.map(
(pair) {
return new ListTile(
title: new Text(
pair.asPascalCase,
style: _biggerFont,
),
);
},
);
final divided = ListTile
.divideTiles(
context: context,
tiles: tiles,
)
.toList();
return new Scaffold(
appBar: new AppBar(
title: new Text('Saved Suggestions'),
),
body: new ListView(children: divided),
);
},
),
);
}
重启应用,收藏一些单词对后点击列表图标,将进入新页面显示收藏内容,默认带有返回按钮。
Step 7:利用主题改变UI
最后,通过主题自定义应用外观。修改MyApp类的build方法,添加主题设置:
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return new MaterialApp(
title: 'Startup Name Generator',
theme: new ThemeData(
primaryColor: Colors.white,
),
home: new RandomWords(),
);
}
}
重启应用,整个页面背景和AppBar将变为白色。您可以进一步修改主题属性来调整样式。
总结
本章通过逐步实践,介绍了Flutter应用开发的核心概念,包括组件、状态管理、列表、导航和主题。掌握这些基础知识后,您可以继续探索更复杂的Flutter功能。