使用Flutter创建一个app

使用Flutter创建一个app

这次就不费话了,我们直接进入主题,新建一个项目,然后找到pubspec.yaml,然后添加包

english_words: ^3.1.4点击Packages get
使用Flutter创建一个app

添加english_words

现在我们既可以开始写代码

import 'package:flutter/material.dart';
import 'package:english_words/english_words.dart';
void main() => runApp(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),
),
),
);
}
}

写完代码点击闪电我们跑一跑

使用Flutter创建一个app

运行效果

添加一个 有状态的部件(Stateful widget)

Stateless widgets 是不可变的, 这意味着它们的属性不能改变 - 所有的值都是最终的.

Stateful widgets 持有的状态可能在widget生命周期中发生变化. 实现一个 stateful widget 至少需要两个类:

  1. 一个 StatefulWidget类。
  2. 一个 State类。 StatefulWidget类本身是不变的,但是 State类在widget生命周期中始终存在.

在这一步中,你将添加一个有状态的widget-RandomWords,它创建其State类RandomWordsState。State类将最终为widget维护建议的和喜欢的单词对。

  1. 添加有状态的 RandomWords widget 到 main.dart。 它也可以在MyApp之外的文件的任何位置使用,但是本示例将它放到了文件的底部。RandomWords widget除了创建State类之外几乎没有其他任何东西
class RandomWords extends StatefulWidget {
@override
createState() => new RandomWordsState();

}
  1. 添加 RandomWordsState 类.该应用程序的大部分代码都在该类中, 该类持有RandomWords widget的状态。这个类将保存随着用户滚动而无限增长的生成的单词对, 以及喜欢的单词对,用户通过重复点击心形 ❤️ 图标来将它们从列表中添加或删除。
  2. 你会一步一步地建立这个类。首先,通过添加高亮显示的代码创建一个最小类
class RandomWordsState extends State<randomwords> {
}
  1. 在添加状态类后,IDE会提示该类缺少build方法。接下来,你将添加一个基本的build方法,该方法通过将生成单词对的代码从MyApp移动到RandomWordsState来生成单词对。
  2. 将build方法添加到RandomWordState中,如下面高亮代码所示
class RandomWordsState extends State<randomwords> {
@override
Widget build(BuildContext context) {
final wordPair = new WordPair.random();
return new Text(wordPair.asPascalCase);
}
}
  1. 通过下面高亮显示的代码,将生成单词对代的码从MyApp移动到RandomWordsState中
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),
child: new RandomWords(),
),
),
);
}
}

重新启动应用程序

使用Flutter创建一个app

运行效果

创建一个无限滚动ListView

这个我们直接拉取官方文档,我就不过多解释,因为感觉官方写的蛮清楚的。

在这一步中,您将扩展(继承)RandomWordsState类,以生成并显示单词对列表。 当用户滚动时,ListView中显示的列表将无限增长。 ListView的builder工厂构造函数允许您按需建立一个懒加载的列表视图。

  1. 向RandomWordsState类中添加一个_suggestions列表以保存建议的单词对。 该变量以下划线(_)开头,在Dart语言中使用下划线前缀标识符,会强制其变成私有的。
  2. 另外,添加一个biggerFont变量来增大字体大小
class RandomWordsState extends State<randomwords> {
final _suggestions = <wordpair>[];
final _biggerFont = const TextStyle(fontSize: 18.0);
...
}
  1. 向RandomWordsState类添加一个 _buildSuggestions() 函数. 此方法构建显示建议单词对的ListView。
  2. ListView类提供了一个builder属性,itemBuilder 值是一个匿名回调函数, 接受两个参数- BuildContext和行迭代器i。迭代器从0开始, 每调用一次该函数,i就会自增1,对于每个建议的单词对都会执行一次。该模型允许建议的单词对列表在用户滚动时无限增长。
  3. 添加如下高亮的行:
class RandomWordsState extends State<randomwords> {
...
Widget _buildSuggestions() {
return new ListView.builder(
padding: const EdgeInsets.all(16.0),
// 对于每个建议的单词对都会调用一次itemBuilder,然后将单词对添加到ListTile行中
// 在偶数行,该函数会为单词对添加一个ListTile row.
// 在奇数行,该行书湖添加一个分割线widget,来分隔相邻的词对。
// 注意,在小屏幕上,分割线看起来可能比较吃力。
itemBuilder: (context, i) {
// 在每一列之前,添加一个1像素高的分隔线widget
if (i.isOdd) return new Divider();
// 语法 "i ~/ 2" 表示i除以2,但返回值是整形(向下取整),比如i为:1, 2, 3, 4, 5
// 时,结果为0, 1, 1, 2, 2, 这可以计算出ListView中减去分隔线后的实际单词对数量
final index = i ~/ 2;
// 如果是建议列表中最后一个单词对
if (index >= _suggestions.length) {
// ...接着再生成10个单词对,然后添加到建议列表
_suggestions.addAll(generateWordPairs().take(10));
}
return _buildRow(_suggestions[index]);
}
);
}
}
  1. 对于每一个单词对,_buildSuggestions函数都会调用一次_buildRow。 这个函数在ListTile中显示每个新词对,这使您在下一步中可以生成更漂亮的显示行
  2. 在RandomWordsState中添加一个_buildRow函数 :
class RandomWordsState extends State<randomwords> {
...
Widget _buildRow(WordPair pair) {
return new ListTile(
title: new Text(
pair.asPascalCase,
style: _biggerFont,
),
);
}
}
  1. 更新RandomWordsState的build方法以使用_buildSuggestions(),而不是直接调用单词生成库。 更改后如下面高亮部分:
class RandomWordsState extends State<randomwords> {
...
@override
Widget build(BuildContext context) {
final wordPair = new WordPair.random(); // 删除这两行
return new Text(wordPair.asPascalCase);
return new Scaffold (
appBar: new AppBar(
title: new Text('Startup Name Generator'),
),
body: _buildSuggestions(),
);
}
...
}

  1. 更新MyApp的build方法。从MyApp中删除Scaffold和AppBar实例。 这些将由RandomWordsState管理,这使得用户在下一步中从一个屏幕导航到另一个屏幕时, 可以更轻松地更改导航栏中的的路由名称。
  2. 用下面高亮部分替换最初的build方法:
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return new MaterialApp(
title: 'Startup Name Generator',
home: new RandomWords(),
);
}
}

最终代码如下,重新新启动应用程序或者热重载一下。你应该看到一个单词对列表。尽可能地向下滚动,您将继续看到新的单词对。

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),
child: new RandomWords(),
),
),

);
}
}
class RandomWords extends StatefulWidget {
@override
createState() => new RandomWordsState();
}
//class RandomWordsState extends State<randomwords> {
// @override
// Widget build(BuildContext contex) {
// final wordPair = new WordPair.random();
// return new Text(wordPair.asPascalCase);
// }
//}
class RandomWordsState extends State<randomwords> {
final _suggestions = <wordpair>[];
final _biggerFont = const TextStyle(fontSize: 18.0);
@override
Widget build(BuildContext context) {
return new Scaffold (
// appBar: new AppBar(
// title: new Text('Startup Name Generator'),
// ),
body: _buildSuggestions(),
);
}
Widget _buildSuggestions() {
return new 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 new 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]);
}

);
}
Widget _buildRow(WordPair pair) {
return new ListTile(
title: new Text(
pair.asPascalCase,
style: _biggerFont,
),
);
}
}

然后我们就生成了一个无线滚动的listvIew。

使用Flutter创建一个app

无线滚动的listvIew

明天写交互。其实可以直接看文档,官方的文档还是写的比较清楚的。


分享到:


相關文章: