这是一份创建Flutter app的指南,如果你熟悉面向对象的语言,就可以很容易地完成.不需要有dart的经验
这份指南分两部分,都可以在codelab里找到.https://codelabs.developers.google.com/
1.创建Flutter app启动器
2.使用额外的包
3.添加有状态的控件
4.创造一个无限滚动的ListView
你会在第一部分做的事:
将实现一个移动app,带有公司与名字等信息.实现一个滚动的列表.图略.
可以学到的:
如何写一个在android与ios上看着本地化Flutter app.
Flutter app的基础结构
查找并使用包
使用热加载来快速开发
如何实现有状态的控件
如何创建无限滚动的懒加载的列表
1.创建Flutter app
基于模板,创建一个简单的Flutter app,使用https://flutter.io/get-started/test-drive/#create-app指南.把名字修改为startup_namer.
编辑lib/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'),
),
),
);
}
}
运行,https://flutter.io/get-started/codelab/images/android-hello-world-frame.png,查看效果
提示:
这个示例,创建了一个Material app,Material 是一个可视化的设计语言.基于移动与web标准的.Flutter提供了很多Material 控件.
主方法,的=>操作符,表明它是一行方法.
app继承自StatelessWidget,它本身是一个控件,在Flutter,里所有的东西都是控件.包含位置,补白,布局.
在Material库中的Scaffold控件,提供了默认屏幕内的标题,内容.控件子树可以非常复杂.
一个控件主要工作是提供build()方法.描述如何展示控件.
内容部分,像这个示例是居中的控件,包含一个文本框子控件.居中控件,让子树中的内容居屏幕中.
2.使用额外的包
这步骤中,开始使用一些开源的包enblish_words,它包含了数千个常用的英文词与方法.
可以在https://pub.dartlang.org/flutter/或像其它开源包的服务器中,找到这个包.
pubspec文件管理着这些Flutter app的依赖,pubspec.yaml添加英文词到依赖中
dependencies:
flutter:
sdk: flutter
cupertino_icons: ^0.1.0
english_words: ^3.1.0
在as中查看,点击Packages get,会就把包导入工程.会在控制台看到
> flutter packages get
Running "flutter packages get" in startup_namer...
Process finished with exit code 0
执行Packages get也会产生pubspec.lck文件.文件包含着导入的包的版本号.
在lib/main.dart里导入包
import 'package:flutter/material.dart';
import 'package:english_words/english_words.dart';
as会提示导入的库.稍后会渲染出来导入的字符串提示,告诉你导入的包未使用.
使用英文单词包,产生文本而不是Hello World字符串.
内容部分修改:
import 'package:english_words/english_words.dart';
body: Center(
//child: Text('Hello World'), // Replace the highlighted text...
child: Text(wordPair.asPascalCase), // With this highlighted text.
),
其它略了与前面同
运行以后,使用热加载
添加有状态的控件
无状态的控件是不可变的.表示你不能够修改它.所有的值是final的.
有状态的控件,包含着一个State状态,在生命周期.中会改变状态.实现有状态的控件至少需要两个类.状态类和控件类.有状态的StatefulWidget类本身也是不可变的,但状态有持久化作用,在生命周期中,它是可变的.
这一步中,添加一个有状态的控件.RandomWords,它创建一个有状态的类,RandomWordsState,然后添加到app中.
在main.dart下面创建最小化的状态类
class RandomWordsState extends State {
// TODO Add build method
}
它依赖RandomWords类,稍后添加.
main.dart下面添加
class RandomWords extends StatefulWidget {
@override
RandomWordsState createState() => new RandomWordsState();
}
添加完状态类,ide会完成缺失的build方法.添加一的基础的build方法,产生字符对.从MyApp移到RandomWordsState
class RandomWordsState extends State {
@override
Widget build(BuildContext context) {
final wordPair = WordPair.random();
return Text(wordPair.asPascalCase);
}
}
移除旧的代码.然后重新运行.
创建无限滚动的列表
这一步中,扩展RandomWordsState,产生一个无限的字符对列表.当用户滚动时,列表显示一个ListView控件,无限增长.ListView的构造工厂方法,允许你懒加载.
添加_suggestions到RandomWordsState类中.来保存建议的字符对.添加biggerFont变量,让字体变大.
class RandomWordsState extends State {
final _suggestions = [];
final _biggerFont = const TextStyle(fontSize: 18.0);
...
}
现在添加_buildSuggestions()方法到RandomWordsState类中,这个方法构造一个ListView来显示建议
ListView类提供一个构造属性,itemBuilder,这个工厂的回调方法,是一个异步方法.两个参数,BuildContext与row游标i.当调用时游标从0开始增加. 这种模式允许用户滚动时无限增长.
添加方法:
class RandomWordsState extends State {
...
Widget _buildSuggestions() {
return ListView.builder(
padding: const EdgeInsets.all(16.0),
// The itemBuilder callback is called once per suggested word pairing,
// and places each suggestion into a ListTile row.
// For even rows, the function adds a ListTile row for the word pairing.
// For odd rows, the function adds a Divider widget to visually
// separate the entries. Note that the divider may be difficult
// to see on smaller devices.
itemBuilder: (context, i) {
// Add a one-pixel-high divider widget before each row in theListView.
if (i.isOdd) return Divider();
// The syntax "i ~/ 2" divides i by 2 and returns an integer result.
// For example: 1, 2, 3, 4, 5 becomes 0, 1, 1, 2, 2.
// This calculates the actual number of word pairings in the ListView,
// minus the divider widgets.
final index = i ~/ 2;
// If you've reached the end of the available word pairings...
if (index >= _suggestions.length) {
// ...then generate 10 more and add them to the suggestions list.
_suggestions.addAll(generateWordPairs().take(10));
}
return _buildRow(_suggestions[index]);
}
);
}
}
添加buildRow()方法.这个方法显示一个列表项.
Widget _buildRow(WordPair pair) {
return ListTile(
title: Text(
pair.asPascalCase,
style: _biggerFont,
),
);
}
更新_buildSuggestions()方法.直接调用库来产生词.
@override
Widget build(BuildContext context) {
final wordPair = WordPair.random(); // Delete these two lines.
return Text(wordPair.asPascalCase);
return Scaffold (
appBar: AppBar(
title: Text('Startup Name Generator'),
),
body: _buildSuggestions(),
);
}
更新build方法,修改标题,改变主屏为RandomWords控件
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Startup Name Generator',
home: RandomWords(),
);
}
}
重新运行app.
无论滚多远,都可以看到有字符对产生