带你Flutter带你Fly之单词收藏
本次笔者将实现这样一个效果:收藏列表的单词。并可点击页面右上角按钮展现收藏的单词
收藏个别单词.png
准备工作
打开Vs Code编辑器,快捷键 Crtl+Shift+P 打开 Commadn Palette命令板,输入 >Flutter:New Project 新建一个Flutter应用
输入应用名后,保存文件后,项目会自动进行创立,创立完毕之后,main.dart 文件会被自动打开。接下来,我们就对这个 main.dart 进行修改
一、熟习 main.dart
把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: "First Flutter App", home: new Scaffold( appBar: new AppBar( title: new Text("My First Flutter App "), ), body: new Center( child: new Text("This is my first flutter app"), ), ), ); }}打开模拟器或者者真机,按F5,运行代码
1.png
代码还是比较简单的,主要有如下几个知识点:
- main 方法采用了胖箭头 ( => ) 表示法,这是一种用于单行函数或者方法的简写。
- 该app继承了使它本身成为一个 widget 的 StatelessWidget 类。在 Flutter 中,大多数时候一切都可以看作 widget , 包括 alignment,padding 和 layout
- Material 库中的 Scaffold widget 提供了默认的应用栏 (app bar),标题和构成主页面 widget 树结构的 body 属性
- widget 的主要工作是提供一个build()方法,形容如何根据其余更低层级的 widget,来对这个 widget 进行展现
- widget 树由包含了 Text child widget 的 Center widget 组成。Center widget 可将它的所有子树对齐到屏幕中心
二、使用外部package
这一步我们学习引入外部的package来随机生成一对英文单词。借助名为 english_words的开源软件包,它包含数千个最常用的英文单词以及少量实用功能
1.在 pubspec.yaml 文件中, 将 english_words(3.1.0或者更高版本)增加到依赖列表
增加依赖库.png
2.Crtl+S 保存后它会自动将包拉入到项目中。或者者直接控制台输入命令 flutter packages get
代码中导入该库
import 'package:english_words/english_words.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: "first flutter app", home: new Scaffold( appBar: new AppBar( title: new Text("My First Flutter App "), ), body: new Center( //child: new Text("This is my first flutter app"), child: new Text(wordpair.asCamelCase), //驼峰方式命名随机生成的单词 ), ), ); }}
first app.png
三、增加有状态的widget
在前面的代码中, MyApp 类继承的是 StatelessWidget 类。但Stateless widgets是不可改变的,这意味着它们的属性不能改变,所有的值都是 final 的
实现一个有状态的 widget 至少需要两个类:StatefulWidgets类和State类,其中StatefulWidgets类创立了一个State类的实例。StatefulWidget类本身是不可变的,但State类可存在于Widget的整个生命周期中
1.创立一个 RandomWords widget。除了创立 State 类之外几乎没有任何其余代码
class RandomWords extends StatefulWidget{ @override State<StatefulWidget> createState() => new RandomWordsState(); }- 创立 RandomWordsState 类。这个类保存了 RandomWords widget 的状态,该应用程序的大部分代码都放在该类的 build 方法中。
class RandomWordsState extends State<RandomWords>{ @override Widget build(BuildContext context) { final wordPair=new WordPair.random(); return new Text(wordPair.asCamelCase); }3.修改 MyApp 中代码,重新启动应用,热重载后,效果和上图一样
class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { //final wordpair=new WordPair.random(); //随机生成一对单词 return new MaterialApp( title: "first flutter app", home: new Scaffold( appBar: new AppBar( title: new Text("My First Flutter App "), ), body: new Center( //child: new Text("This is my first flutter app"), // child: new Text(wordpair.asCamelCase), //驼峰方式命名随机生成的单词 child: new RandomWords(), //直接调用自己设置的 RandomWords widget ), ), ); }}四、创立一个ListView展现英文单词
生成并展现词组列表,需要扩展 RandomWordsState 类。当客户滑动列表,ListView widget 中显示的列表将无限增长。 ListView 的 builder 工厂构造函数允许按需建立一个推迟加载的列表 view。
1.准备一个数组用来存储随机生成的单词
class RandomWordsState extends State<RandomWords>{ var _suggestWords = <WordPair>[]; //下划线表示私有 //字体大小 final _biggerFont = const TextStyle(fontSize: 18.0);}- 向 RandomWordsState 类增加一个_buildSuggestionWords() 方法,用于构建一个显示词组的 ListView。并调用 _buildRow 方法将每一个单词放入ListView的对应的item上
Widget _buildSuggestionWords(){ return new ListView.builder( padding: const EdgeInsets.all(16.0), itemBuilder: (context,i){ if(i.isOdd) return new Divider(); //listview的条目是奇数,画一条分割线 final index = i ~/2; // ~/ 表示除的结果取整 if(index >= _suggestWords.length){ _suggestWords.addAll(generateWordPairs().take(10)); //生成10个单词放入数组中 } return _buildRow(_suggestWords[index]); }, ); }- _buildRow 方法每次会在一个 ListTile widget中展现一条新词组
Widget _buildRow(WordPair suggestWord) { return new ListTile( title: new Text(suggestWord.asPascalCase, style: _biggerFont, ), ); }4.升级 RandomWordsState 类的 build 方法来使用 _buildSuggestions() 函数,而不是直接调用单词生成库
@override Widget build(BuildContext context) { return new Scaffold( appBar: new AppBar( title: new Text("Generate English Words"), ), body: _buildSuggestionWords(), ); }5.升级 MyApp 类的 build 方法,使用 RandomWords widget 来生成一个不断滚动的listview
class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { //final wordpair=new WordPair.random(); //随机生成一对单词 return new MaterialApp( title: "first flutter app", home: new RandomWords(), ); }}
未收藏.png
五、点击爱心收藏
为每一行增加可点击的心形图标。当客户点击列表中的条目,切换其“收藏”状态,词组就会增加到收藏栏,或者从已保存词组的收藏栏中删除。
1.增加一个 Set 集合 _saved 到 RandomWordsState 类。保存客户收藏的词组。Set 集合比 List 更适用于此,由于它不允许重复元素。
2.在 _buildRow 函数中,增加 alreadySaved 标志检查来确保一个词组还没有被增加到收藏,并增加一个心形图标来使用收藏功能
Widget _buildRow(WordPair suggestWord) { final alreadySaved = _saved.contains(suggestWord); return new ListTile( title: new Text(suggestWord.asPascalCase, style: _biggerFont, ), trailing: new Icon(//根据单词能否收藏决定能否点亮爱心 alreadySaved ? Icons.favorite : Icons.favorite_border, color: alreadySaved ? Colors.red : null, ) ); }3.尽管上面出现了心形图标,但还没有交互功能。在 _buildRow 函数中使心形可点击。假如词条已经被加入收藏,再次点击它将从收藏中删除
Widget _buildRow(WordPair suggestWord) { final alreadySaved = _saved.contains(suggestWord); return new ListTile( title: new Text(suggestWord.asPascalCase, style: _biggerFont, ), trailing: new Icon( //根据单词能否收藏决定能否点亮爱心 alreadySaved ? Icons.favorite : Icons.favorite_border, color: alreadySaved ? Colors.red : null, ), onTap: (){ //点击每个条目进行收藏单词和取消收藏 setState(() { if(alreadySaved) _saved.remove(suggestWord); else _saved.add(suggestWord); }); } , ); }在 Flutter 的响应式风格框架中,调用 setState() ,将为 State 对象触发 build() 方法的调用,从而实现对UI的升级。
收藏个别单词.png
六、跳转到收藏页面
增加一个显示收藏夹的新页面(在 Flutter 中称为 route(路由))。在 Flutter 中, Navigator 管理着包含了应用程序所有路由的一个堆栈。将一个路由push到 Navigator 的堆栈,将显示升级为新页面路由。将一个路由 pull 出 Navigator 的堆栈,显示将返回到前一个页面路由。
1.在 RandomWordsState 类的 build 方法中,向 AppBar 增加一个列表图标。当客户点击列表图标时,跳转到收藏的页面
@override Widget build(BuildContext context) { return new Scaffold( appBar: new AppBar( title: new Text("Generate English Words"), actions: <Widget>[ //增加列表图标按钮,按下将调用_pushSaved 方法 new IconButton(icon: new Icon(Icons.format_list_bulleted),onPressed: _pushSaved), ], ), body: _buildSuggestionWords(), ); }2.向 RandomWordsState 类增加一个 _pushSaved() 方法,这个方法用于跳转到收藏单词的页面
void _pushSaved(){ //跳转到新的页面 Navigator.of(context).push( //函数调用增加到 Navigator.push 中作为参数,如高亮代码所示,将路由 push 到 Navigator 的堆栈中。 new MaterialPageRoute( builder: (context){ //把喜爱的单词放入listview的item中 final tiles=_saved.map( (pair){ return new ListTile( title: new Text(pair.asPascalCase, style: _biggerFont, ), ); }, ); //为每个 ListTile widget 之间增加水平间距。divided变量保存最终生成的所有行,并用 toList() 函数转换为列表。 final divided = ListTile.divideTiles( context: context, tiles: tiles, ).toList(); //新的页面,新页面的body属性由包含多个 ListTile widget 的 ListView 组成。 return new Scaffold( appBar: new AppBar( title: new Text('Favorite Words')), body: new ListView(children: divided), ); }, ), );}}
展现收藏单词.png
1. 本站所有资源来源于用户上传和网络,如有侵权请邮件联系站长!
2. 分享目的仅供大家学习和交流,您必须在下载后24小时内删除!
3. 不得使用于非法商业用途,不得违反国家法律。否则后果自负!
4. 本站提供的源码、模板、插件等等其他资源,都不包含技术服务请大家谅解!
5. 如有链接无法下载、失效或广告,请联系管理员处理!
6. 本站资源售价只是摆设,本站源码仅提供给会员学习使用!
7. 如遇到加密压缩包,请使用360解压,如遇到无法解压的请联系管理员
开心源码网 » 带你Flutter带你Fly之单词收藏