Flutter基础—应用实例
总结之前学习的概念,编写一个完整的应用实例。假设我们使用一个网络购物的应用程序,它展示出售的各种商品和存放准备购买商品的购物车。首先定义一个展示类ShoppingListItem.dart:
import 'package:flutter/material.dart';
class Product {const Product({this.name});final String name;
}
typedef void CartChangedCallback(Product product, bool inCart);
class ShoppingListItem extends StatelessWidget {ShoppingListItem({Product product, this.inCart, this.onCartChanged}): product = product,super(key: new ObjectKey(product));final Product product;final bool inCart;final CartChangedCallback onCartChanged;Color _getColor(BuildContext context) {return inCart ? Colors.black54 : Theme.of(context).primaryColor;}TextStyle _getTextStyle(BuildContext context) {if (!inCart) return null;return new TextStyle(color: Colors.black54,decoration: TextDecoration.lineThrough,);}@overrideWidget build(BuildContext context) {return new ListTile(onTap: () {onCartChanged(product, !inCart);},leading: new CircleAvatar(backgroundColor: _getColor(context),child: new Text(product.name[0]),),title: new Text(product.name, style: _getTextStyle(context)),);}
}
ShoppingListItem控件遵循无状态控件的通用模式,将在构造函数中接收到的值存储在final成员变量中,然后在build函数执行时使用。例如布尔值inCart在两个视觉效果之间切换:一个使用当前主题的颜色,另一个使用灰色。
当用户点击列表项时,控件不会直接修改inCart的值,但是控件从父控件接收onCartChanged函数。此模式允许你在控件较高的层次结构中存储状态,这样使状态的持续时间更长。在极端情况下,存储在runApp的控件状态在应用程序的生命周期内保持不变。
当父控件接收到onCartChanged回调,父控件会更新其内部状态,这将触发父控件重建并使用新的inCart值创建ShoppingListItem的新实例。尽管父控件在重建时创建了ShoppingListItem的新实例,但该操作很节省,因为框架会将新构建的控件与之前构建的控件时进行比较,并将有差异的部分应用于底层渲染对象。
下面编写存储可变状态的父控件:
import 'package:flutter/material.dart';
import 'ShoppingListItem.dart';
class ShoppingList extends StatefulWidget {ShoppingList({Key key, this.products}) : super(key: key);final List<Product> products;@override_ShoppingListState createState() => new _ShoppingListState();
}
class _ShoppingListState extends State<ShoppingList> {Set<Product> _shoppingCart = new Set<Product>();void _handleCartChanged(Product product, bool inCart) {setState(() {if (inCart)_shoppingCart.add(product);else_shoppingCart.remove(product);});}@overrideWidget build(BuildContext context) {return new Scaffold(appBar: new AppBar(title: new Text('购物清单'),),body: new ListView(children: widget.products.map((Product product) {return new ShoppingListItem(product: product,inCart: _shoppingCart.contains(product),onCartChanged: _handleCartChanged,);}).toList(),),);}
}
final List<Product> _kProducts = <Product>[new Product(name: '鸡蛋'),new Product(name: '面粉'),new Product(name: '巧克力脆片'),
];
void main() {runApp(new MaterialApp(title: 'Flutter教程',home: new ShoppingList(products: _kProducts),),);
}
类ShoppingList继承了StatefulWidget,这意味着这个控件存储可变状态,当ShoppingList首次插入到树中,框架调用createState函数在树中相关联的位置创建一个新的_ShoppingListState实例(注意:通常命名中带有下划线的State子类,说明它们是私有类)。当该控件的父控件重建时,父控件会创建一个新的ShoppingList实例,但框架将重用已经在树上的_ShoppingListState实例,而不会再次调用createState函数。
要访问当前ShoppingList的属性,_ShoppingListState可以使用其config属性。如果父控件重建并创建一个新的ShoppingList,_ShoppingListState也将使用新的config值重建。如果想要在config属性更改时收到通知,可以覆盖didUpdateConfig函数,它通过oldConfig将旧配置与当前config进行比较。
当处理onCartChanged回调时,_ShoppingListState通过从_shoppingCart中添加或删除一个产品来改变其内部状态。为了向框架通知它改变了内部状态,它在setState中封装这些调用。调用setState将控件标记为dirty,并安排它在应用程序下次需要更新屏幕时重建。如果在修改控件内部状态时忘记调用setState,框架不会知道控件是dirty的,可能不会调用控件的build函数,这意味着用户界面不会更新以反映更改的状态。
通过这种方式管理动态,不再需要单独编写代码来创建和更新子控件。相反,只需要实现构建函数,即可处理这两种情况。
Flutter基础—应用实例相关推荐
- Flutter基础—你好,Flutter!
什么是Flutter Flutter是一个移动应用程序的软件开发工具包(SDK),用一个代码库构建高性能.高保真的iOS和Android应用程序.目标是使开发人员能够为Android和iOS提供自然的 ...
- Flutter基础(四)开发Flutter应用前需要掌握的Basic Widget
本文首发于公众号「刘望舒」 关联系列 ReactNative入门系列 React Native组件 Flutter基础系列 前言 学完了Dart语言,接下来就可以学习Widget了,Flutter的U ...
- Flutter基础篇(2)-- 老司机用一篇博客带你快速熟悉Dart语法
版权声明:本文为博主原创文章,未经博主允许不得转载.https://www.jianshu.com/p/3d927a7bf020 转载请标明出处: https://www.jianshu.com/p/ ...
- 一份超级详细的Flutter基础组件练习示例,请查收!
学习B站技术胖的flutter基础课程整理的示例,为了平时方便查阅,同时希望能和大家一同进步~ Flutter基础组件 Hello world import 'package:flutter/mate ...
- Flutter基础(三)Dart快速入门
本文首发于公众号「刘望舒」 关联系列 ReactNative入门系列 React Native组件 Flutter基础系列 前言 Dart是Flutter SDK指定的语言,因此要学习Flutter, ...
- 《Dreamweaver CS6完美网页制作——基础、实例与技巧从入门到精通》——1.3 常用网页设计软件...
本节书摘来自异步社区<Dreamweaver CS6完美网页制作--基础.实例与技巧从入门到精通>一书中的第1章,第1.3节,作者:何新起 更多章节内容可以访问云栖社区"异步社区 ...
- Nginx基础配置实例需求分析
前面我们已经对Nginx服务器默认配置文件的结构和涉及的基本指令做了详细的阐述.通过这些指令的合理配置,我们就可以让一台Nginx服务器正常工作,并且提供基本的web服务器功能. 接下来我们将通过一个 ...
- matlab基础与实例教程,MATLAB基础与实例教程
系统全面,实例丰富 考虑到Matlab进行仿真和运算分析时的基础知识和实践操作,讲解从基础的变量.函数.数据类型等入手,涉及到数学分析.图形可视化.Simulink仿真.文件读写等,全面地介绍了Mat ...
- nginx ---- Nginx服务器基础配置实例
前面我们已经对Nginx服务器默认配置文件的结构和涉及的基本指令做了详细的阐述.通过这些指令的合理配置,我们就可以让一台Nginx服务器正常工作,并且提供基本的web服务器功能. 接下来我们将通过一个 ...
最新文章
- i.MX6UL: i.MX 6UltraLite处理器 - 低功耗,安全,Arm® Cortex®-A7内核
- pytorch 半精度,提升pytorch推理性能
- 如何正确的进行网站入侵渗透测试
- 【CyberSecurityLearning 63】CSRF攻击
- Prefix Sum Primes
- LeetCode 1042. 不邻接植花(图的数据结构)
- 个人vscode插件配置全记录
- 总结之Unix的基础知识
- 电力系统——基于10机39节点的电力系统仿真(Matlab)
- 单播、多播(组播)和广播的区别
- java制作数字彩虹雨的代码,canvas+gif.js打造自己的数字雨头像的示例代码
- myd导入mysql_数据库是.frm,.myd,myi备份如何导入mysql
- 美国主要经济数据解注释
- 什么是arXiv.org?
- android build.prop的参数
- C语言-字符0、数字0和‘\0’的区别
- 计算机控制室防火危险级为,8.2 空气调节 - 【已作废】火力发电厂与变电站设计防火规范 GB50229-2006 - 消防规范大全 - 消防资源网!...
- idea安装plantuml插件画流程图
- python搭建内网网站,python搭建服务器
- C#中的static,interface,virtual,abstract,override的用法