带你Flutter带你Fly之单词收藏

作者 : 开心源码 本文共6323个字,预计阅读时间需要16分钟 发布时间: 2022-05-12 共235人阅读

本次笔者将实现这样一个效果:收藏列表的单词。并可点击页面右上角按钮展现收藏的单词

收藏个别单词.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();  }
  1. 创立 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);}
  1. 向 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]);               },            );    }
  1. _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之单词收藏

发表回复