【flutter】手把手写flutter入门的例子:无限滚动ListView
1、Hello world
我使用的是macbook pro的,编辑器VS。
- 按F1(有touchbar的机子按住fn可见F1)呼出命令输入框;
- 输入字符Flutter,在命令候选列表中选择Flutter: New Project;
- 随后让你填写项目名称和选择项目存放路径。
2、在屏幕的中心显示“Hello World”
目标:在屏幕的中心显示“Hello World”
- 替换 lib/main.dart.
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return new MaterialApp(
title: 'welcome to start name Demo',
home: new Scaffold(
appBar: new AppBar(
title: new Text('你好,saucxs'),
),
body: new Center(
child: new Text('Hello world'),
)
)
);
}
}
- 运行之后的页面

- 分析
- 创建的是一个Material APP。Material是一种标准的移动端和web 端的视觉设计语言。flutter提供了一套丰富的Material widgets。
- main函数使用了
=>符号,Dart中单行函数或者方法的简写 - MyApp继承了StatelessWidget,这将使应用本身也成为一个widget。在flutter中,大多数的都是widget,包括对齐的alignment,填充padding,布局layout。
- scaffold是material library中提供的一个widget,他提供了默认的导航栏appBar,标题和包含主屏幕widget树的body属性。widget树可以很复杂。
- widget的主要工作就是提供一个build方法来描述如何根据其他较低级别的widget来显示自己。
- 本例子中的body的widget树中包含了一个center widget,center widget又包含了一个text子的widget。center widget可以将其子widget树对齐到屏幕中心
3、如何使用外部包
开始使用一个名为english_words的开源软件包 ,其中包含数千个最常用的英文单词以及一些实用功能。
可以在pub.dartlang.org上找到一些包,比如english_words软件包
- pubspec文件管理Flutter应用程序的assets(比如图片,package等)。在pubspec.yaml中,将english_words(3.1.0及以上)添加到依赖列表中,比如

- 在lib/main.dart中,引入
english_words
import 'package:flutter/material.dart';
import 'package:english_words/english_words.dart';
- 使用english worlds 包生成文本来替换字符串 使用的是驼峰命名法,表示字符串中每个单词都以大写字母开头。
import 'package:flutter/material.dart';
import 'package:english_words/english_words.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
final wordPair = new WordPair.random();
return new MaterialApp(
title: 'welcome to start name Demo',
home: new Scaffold(
appBar: new AppBar(
title: new Text('你好,saucxs'),
),
body: new Center(
// child: new Text('Hello world'),
child: new Text(wordPair.asPascalCase),
)
)
);
}
}
PS: 每一次热重启,都是生成不同的英文。
4、添加一个有状态的部件(stateful widget)
Stateless widget 是不可变的,意味着属性不能改变,所有的值都是最终的值。
Stateful widget 持有的状态可能在widget生命周期中发生变化,实验一个 stateful widget至少需要两个类。
- 一个StatefulWidget类
- 一个State类。StatefulWidget类本身是不变的,但是State类在widget生命周期中始终存在。
我们先添加一个有状态的widget-RandomWords,它创建其State类RandomWordsState。State类将最终为widget维护建议的和喜欢的单词对。
- 第一步:添加有状态的RandomWords widget到main.dart。也可以是MyApp之外的文件的任何位置,但是我们首先放在文件的底部。RandomWords widget除了创建State类之外几乎没有其他任何东西。
class RandomWords extends StatefulWidget {
@override
createState() => new RandomWordsState();
}
- 第二步:添加RandomWordsState类。程序大部分代码在这个类中,该类持有RandomWords widget的状态。这个类将保存随着用户滚动而无线增长的生成的单词对,以及喜欢的单词对,用户通过重复覅按季心形图表来将他们从列表中添加和删除。
新建这样一个类,首先,通过添加高亮显示代码创建一个最小的类。
class RandomWordsState extends State<RandomWords> {
}
- 第三步:在添加状态类后,接下来我们添加一个基本的build方法,该方法通过将生成的单词对的代码从MyApp移动到RandomWordsState来生成单词对。
将build方法添加到RandomWordState中,代码如下:
class RandomWordsState extends State<RandomWords> {
@override
Widget build(BuildContext context) {
final wordPair = new WordPair.random();
return new Text(wordPair.asPascalCase);
}
}
- 第四步:通过修改MyApp类,将生成单词对的代码从MyApp中移动到RandomWordsState中。
class MyApp extends StatelessWidget {
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
// final wordPair = new WordPair.random();
return new MaterialApp(
title: 'welcome to start name Flutter Demo',
home: new Scaffold(
appBar: new AppBar(
title: new Text('你好,saucxs'),
),
body: new Center(
// child: new Text('Hello world'),
// child: new Text(wordPair.asPascalCase),
child: new RandomWords(),
)
)
);
}
}
重新启动应用程序。跟之前的一样,每一次热重载,都会生成新的单词。
5、创建一个无限滚动ListView
上述中的RandomWordsState类,我们继承这个类,并生成显示单词对列表。当用户滚动时,ListView中显示的列表将无限的增长。ListView的build工厂构造函数允许按需建立一个懒加载的列表视图。
- 第一步:向RandomWordsState类中添加一个_suggestions列表中保存建议的单词对。对变量以下划线_开头的,Dart语言中使用下划线前缀的标识符,会强制变成私有的。
另外,添加一个biggerFont变量来增大字体大小。
class RandomWordsState extends State<RandomWords> {
final _suggestions = <WordPair>[];
final _biggerFont = const TextStyle(fontSize: 18.0);
...
}
- 第二步:向RandomWordsState类中添加一个
_buildSuggestion()函数,此方法构建显示建议单词对的ListView。
ListView类提供了一个builder属性,itemBuilder值是一个匿名回调函数,接受两个参数:BuildContext和迭代器i。迭代器从0开始,没调用一次该函数,i就会自增1,对于每个建议单词对都会执行一次。该模型允许建议的单词对列表在用户滚动时无限增长。
代码如下:
class RandomWordsState extends State<RandomWords> {
final _suggestions = <WordPair>[];
final _biggerFont = const TextStyle(fontSize: 18.0);
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]);
}
);
}
}
- 第三步:对于每一个单词对,_buildSuggestions函数都会调用一次_buildRow。这个函数在ListTile中显示每个新词对,这样在下一步中可以生成更漂亮的显示行。
在RandomWordsState中添加一个_buildRow函数:
class RandomWordsState extends State<RandomWords> {
...
Widget _buildRow(WordPair pair) {
return new ListTile(
title: new Text(
pair. asPascalCase,
style: _biggerFont,
),
);
}
}
- 第四步:更新RandomWordsState的build方法以使用_buildSuggestions(),而不是直接调用单词生成库。更改如下:
class RandomWordsState extends State<RandomWords> {
...
@override
Widget build(BuildContext context) {
return new Scaffold (
appBar: new AppBar(
title: new Text('Startup Name Generator'),
),
body: _buildSuggestions(),
);
}
...
}
- 第五步:更新MyApp的build方法。从MyApp中删除Scaffold和AppBar实例。 这些将由RandomWordsState管理,这使得用户在下一步的从一个屏幕导航到另一个屏幕,可以轻松的更改导航栏中的路由名称。
替换最初的build方法:
class MyApp extends StatelessWidget {
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return new MaterialApp(
title: 'welcome to start name Flutter Demo',
home: new RandomWords(),
);
}
}
重启应用程序,你可以看到一个单词对列表。尽可能的向下滚动,将继续看到新的单词对。

6、欢迎关注
show me code:github.com/saucxs/flut…
后续会出更多知识体系构建,技术分享,项目实战,实验室等,欢迎关注本公众号:[松宝写代码]

微信公众号:[松宝写代码] songEagle开发知识体系构建,技术分享,项目实战,实验室,带你一起学习新技术,总结学习过程,让你进阶到高级资深工程师,学习项目管理,思考职业发展,生活感悟,充实中成长起来。问题或建议,请公众号留言。
微信群:【写代码】研发进阶群 一个成长交流的产研群,帮忙拉产研的同学们进群,聚聚人气😘😘。 每一个开发同学都应该形成自己的知识体系,做到提纲挈领🧐🧐🧐
7、各种福利
关注微信公众号:[松宝写代码],有各种福利。
「字节跳动」内推福利:
1、社招内推

2、实习生内推

3、校招内推
官网地址,投递时候填写内推码:8J5ZSB8