参考: 编写您的第一个 Flutter App

Flutter开发我的收藏列表

  • 准备数据:列表数据使用数组存储,选中的数据可以使用Set存储(因为set可以自动去重)。
  • 界面列表:使用ListView
  • 界面跳转:可以使用Navigator

先看下官网的效果

准备

相信看过前面的文章的同学,对于页面创建已经比较熟悉了。

  1. pubspec.yaml中,将english_words添加到依赖项列表:
dependencies:flutter:sdk: fluttercupertino_icons: ^0.1.0english_words: ^3.1.0
  1. 在 引用的页面中导入english_words:
import 'package:flutter/material.dart';
import 'package:english_words/english_words.dart';
  1. 先创建一个页面,页面代码如下:

查看ListView的源码,发现其最终是继承自 StatelessWidget,所以它的状态是唯一的。但是要实现的ListView中的数据是动态变化的,所以需要使用StatefulWidget来动态改变ListView中的数据。 使用StatefulWidget组件需要自己控制在不同情况下的显示状态,所以需要实现State类来告诉StatefulWidget类不同情况下如何展示。

创建一个动态变化的组件类MyFavoriteList,用于表示要显示的ListView:

import 'package:flutter/material.dart';
import 'package:english_words/english_words.dart';class MyFavoriteList extends StatelessWidget {@overrideWidget build(BuildContext context) {// TODO: implement buildreturn MyFavoriteListView();}
}class MyFavoriteListView extends StatefulWidget {@overrideState<StatefulWidget> createState() {// TODO: implement createStatereturn MyFavoriteListViewState();}
}class MyFavoriteListViewState extends State <MyFavoriteListView> {@overrideWidget build(BuildContext context) {// TODO: implement buildreturn Scaffold(appBar: AppBar(title: Text('我的收藏列表'),),body: Text('我的收藏列表'),);}
}

  1. 创造数据集和构建ListView
    添加如下两个方法到MyFavoriteListViewState类中,表示创造数据集和构建ListView:当用户滚动时,ListView中显示的列表将无限增长。 ListView的builder工厂构造函数允许您按需建立一个懒加载的列表视图。
final _suggestions = <WordPair>[];final _biggerFont = const TextStyle(fontSize: 18.0);Widget _buildSuggestions() {return new ListView.builder(padding: const EdgeInsets.all(16.0),// 对于每个建议的单词对都会调用一次itemBuilder,然后将单词对添加到ListTile行中// 在偶数行,该函数会为单词对添加一个ListTile row.// 在奇数行,该函数会添加一个分割线widget,来分隔相邻的词对。// 注意,在小屏幕上,分割线看起来可能比较吃力。itemBuilder: (context, i) {// 在每一列之前,添加一个1像素高的分隔线widgetif (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]);});}Widget _buildRow(WordPair pair) {return new ListTile(title: new Text(pair.asPascalCase,style: _biggerFont,),);}

代码中有详细的注释,但是为了方便理解,这里还是给出一点解释:

  1. _buildSuggestions方法就是返回一个ListView
  2. _buildRow方法就是返回ListView中的一行(ListTile)如何展示
  3. _suggestions.addAll(generateWordPairs().take(10));就是每次添加10个数据到显示数组中

更新MyFavoriteListViewState的build方法以使用_buildSuggestions()。 更改后如下面高亮部分:

Widget build(BuildContext context) {// TODO: implement buildreturn Scaffold(appBar: AppBar(title: Text('我的收藏列表'),),body: _buildSuggestions(),);}

效果如下:

  1. 第5步: 添加交互
    在这一步中,您将为每一行添加一个可点击的心形 ❤️ 图标。当用户点击列表中的条目,切换其“收藏”状态时,将该词对添加到或移除出“收藏夹”。
  • 5.1 添加一个 _saved Set(集合) 到MyFavoriteListViewState。这个集合存储用户喜欢(收藏)的单词对。 在这里,Set比List更合适,因为Set中不允许重复的值。
  final _suggestions = <WordPair>[];final _biggerFont = const TextStyle(fontSize: 18.0);final _saved = new Set<WordPair>();
  • 5.2 在 _buildRow 方法中添加 alreadySaved来检查确保单词对还没有添加到收藏夹中。
Widget _buildRow(WordPair pair) {final alreadySaved = _saved.contains(pair);...
}
  • 5.3 同时在 _buildRow()中, 添加一个心形 ❤️ 图标到 ListTiles以启用收藏功能。接下来,你就可以给心形 ❤️ 图标添加交互能力了。
Widget _buildRow(WordPair pair) {final alreadySaved = _saved.contains(pair);return new ListTile(title: new Text(pair.asPascalCase,style: _biggerFont,),trailing: new Icon(alreadySaved ? Icons.favorite : Icons.favorite_border,color: alreadySaved ? Colors.red : null,),);
}

提示: 在Flutter的响应式风格的框架中,调用setState() 会为State对象触发build()方法,从而导致对UI的更新

热重载你的应用。你就可以点击任何一行收藏或移除。请注意,点击一行时会生成从心形 ❤️ 图标发出的水波动画

  1. 第6步: 导航到新页面
    添加_pushSaved方法表示如何跳转到新的页面并展示选中的数据:
    分析:
  • 使用Navigator.of(context).push的方式来处理跳转,需要的参数是一个Route
  • 创建页面Route
  • 返回一个新的里面,里面的body内容是一个ListView,展示的是_saved中读取出来的数据

增加函数:

void _pushSaved() {Navigator.of(context).push(new MaterialPageRoute(builder: (context) {final tiles = _saved.map((pair) {return new ListTile(title: new Text(pair.asPascalCase,style: _biggerFont,),);},);final divided = ListTile.divideTiles(context: context,tiles: tiles,).toList();return new Scaffold(appBar: new AppBar(title: new Text('Saved Suggestions'),),body: new ListView(children: divided),);},),);
}

最终效果

完整代码

import 'package:flutter/material.dart';
import 'package:english_words/english_words.dart';class MyFavoriteList extends StatelessWidget {@overrideWidget build(BuildContext context) {// TODO: implement buildreturn MyFavoriteListView();}
}class MyFavoriteListView extends StatefulWidget {@overrideState<StatefulWidget> createState() {// TODO: implement createStatereturn MyFavoriteListViewState();}
}class MyFavoriteListViewState extends State <MyFavoriteListView> {final _suggestions = <WordPair>[];final _biggerFont = const TextStyle(fontSize: 18.0);final _saved = new Set<WordPair>();Widget _buildSuggestions() {return new ListView.builder(padding: const EdgeInsets.all(16.0),// 对于每个建议的单词对都会调用一次itemBuilder,然后将单词对添加到ListTile行中// 在偶数行,该函数会为单词对添加一个ListTile row.// 在奇数行,该函数会添加一个分割线widget,来分隔相邻的词对。// 注意,在小屏幕上,分割线看起来可能比较吃力。itemBuilder: (context, i) {// 在每一列之前,添加一个1像素高的分隔线widgetif (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]);});}Widget _buildRow(WordPair pair) {final alreadySaved = _saved.contains(pair);return new ListTile(title: new Text(pair.asPascalCase,style: _biggerFont,),trailing: new Icon(alreadySaved ? Icons.favorite : Icons.favorite_border,color: alreadySaved ? Colors.red : null,),onTap: () {setState(() {if (alreadySaved) {_saved.remove(pair);} else {_saved.add(pair);}});},);}void _pushSaved() {Navigator.of(context).push(new MaterialPageRoute(builder: (context) {final tiles = _saved.map((pair) {return new ListTile(title: new Text(pair.asPascalCase,style: _biggerFont,),);},);final divided = ListTile.divideTiles(context: context,tiles: tiles,).toList();return new Scaffold(appBar: new AppBar(title: new Text('Saved Suggestions'),),body: new ListView(children: divided),);},),);}@overrideWidget build(BuildContext context) {// TODO: implement buildreturn Scaffold(appBar: AppBar(title: Text('我的收藏列表'),actions: <Widget>[new IconButton(icon: new Icon(Icons.list), onPressed: _pushSaved),],),body: _buildSuggestions(),);}
}

总结:实现了数据的存储、状态的改变以及路由的跳转。

Flutter开发之官网的第一个例子实现(46)相关推荐

  1. 几个比较好的IT站和开发库官网

    几个比较好的IT站和开发库官网 1.IT技术.项目类网站 (1)首推CodeProject,一个国外的IT网站,官网地址为:http://www.codeproject.com,这个网站为程序开发者提 ...

  2. 前端-查询参考资料网站/软件/移动端、jQuery开发插件官网

    1.  ECharts(数据可视化模板) https://echarts.apache.org/zh/index.html 2.  CanIuse网站-用于判断技术能在哪些浏览器使用的兼容性(绿色表示 ...

  3. iOS开发——开发者官网注册新设备

    1.第一步登陆苹果开发者中心官网,进入证书栏后如下图:点击All 或者如果是iPhone设备直接点击iPhone也行. 然后点击右上角的[+]号 2.在如下的网页填入姓名和UDID,然后就是继续和下一 ...

  4. 郑建新 计算机 山西大学商务学院官网,迎新第一天 | 这是送给2020级新商院人的独家记忆...

    乘风破浪 筑梦前行 从昨天的相隔千里 到今天的近在咫尺 这美好的相遇,我们已经盼了太久 亲爱的2020级商院人,你好! 点击视频查看报到全景 今天是你踏入大学校园的第一天 这不仅仅是新的学习生活的到来 ...

  5. 用django2.1开发公司官网(上)

    1.在MySQL中新建数据库 show databases;//查看已经有的数据库 create database guanwang; 2.新建django项目guan 1.使用pycharm新建dj ...

  6. HTML5期末考核大作业 基于HTML+CSS+JavaScript仿王者荣耀首页 游戏网站开发 游戏官网设计与实现

  7. javaEE开发如何在oracle官网下载安装jdk?(java SE 8u5 JDK 和 Java EE 7 SDK with JDK 7 U45的区别 )

    做javaEE开发,想到oracle官网上下载JDK使用,但是到底下载那个呢? 一.java SE 8u5 JDK ,如图 二. Java EE 7 SDK with JDK 7 U45,如图: 本人 ...

  8. Keil(MDK)开发软件及STM32芯片包官网下载地址

    Keil(MDK)开发软件官网下载地址: http://www.keil.com/download/product/ STM32芯片包官网下载地址: http://www.keil.com/dd2/p ...

  9. 003-读书笔记-Vue官网 计算属性与监听器

    1.计算属性 1-1 计算属性概述 计算属性也是 Vue 实例的属性,和 data 方法中返回的对象中的属性是等同的存在.通常来说,计算属性可以简单理解: 计算属性其实就是 Vue 实例的一个属性 计 ...

最新文章

  1. 计算机电缆线对成缆系数,计算机电缆绞合系数 - 无图版
  2. Java学习day_012(OOP):抽象类、接口和内部类(上)
  3. angular父组件通过@ViewChild 主动获取子组 件的数据和方法
  4. 应用程序启动器选项卡以及页面内容的设置
  5. python内置变量__complex___Python 内置方法
  6. python查看文件夹文件的所有权限,Python判断某个用户对某个文件的权限
  7. 哈尔滨工程大学ACM预热赛
  8. DRF数据验证+数据存储
  9. win7安装composer
  10. 使用C#发送Http 请求实现模拟登陆(以博客园为例)
  11. SLAM Cartographer(14)Global SLAM的主线业务
  12. 第一章 略说中医的学习与研究(6)
  13. Java之API的使用
  14. 程序下载至开发板 芯片超时无应答,无法连接
  15. 【书山有路】互联网+:从IT到DT 读书笔记
  16. 计算机组装维修diy,ITX装机教程实录:三千元ITX迷你电脑组装电脑全过程-DIY装机...
  17. 点球大战中的概率问题
  18. 联合国发布全球城市经济竞争力20强:中国5城市跻身前20,深圳国内第一
  19. OFDMA,LFDMA以及IFDMA的PAPR对比仿真
  20. CStdioFile类

热门文章

  1. 原创,自己做的一个简单实用的提示小插件,兼容性很好,基本上都兼容!
  2. Mybatis映射文件(3)
  3. [转载]TFS安装配置教程
  4. Jquery Ajax时 error处理 之 parsererror
  5. Nginx之rewrite使用
  6. CentOS 7常用命令
  7. centos6.9安装Tomcat8.0.36
  8. 关于子元素的margin-top对父级容器无效
  9. UpdatePanel AsyncPostBackTrigger PostBackTrigger 区别
  10. jQuery 中的 Ajax