|
1 |
| -## |
2 |
| - |
3 |
| ->本仓库将会持续更新一些「小的功能模块,实现思路」 ,重点是怎么一步步抽取封装 |
4 |
| -
|
5 |
| - |
6 |
| -## Function module |
7 |
| - |
8 |
| -👣 新闻滚动条 11 22 |
9 |
| - |
10 |
| -详解:博文 |
11 |
| - |
12 |
| -效果图: |
13 |
| - |
14 |
| - |
15 |
| - |
16 |
| - |
17 |
| -👣 循环利用tableView |
18 |
| - |
19 |
| -详解:博文 |
20 |
| - |
21 |
| -效果图: |
22 |
| - |
23 |
| - |
24 |
| - |
25 |
| - |
26 |
| - |
27 |
| -👣 无限轮播实现(3张 || 2张) |
28 |
| - |
29 |
| -详解:博文 |
30 |
| - |
31 |
| - |
32 |
| -效果图: |
33 |
| - |
34 |
| - |
35 |
| - |
36 |
| - |
37 |
| - |
38 |
| -👣 Masonry使用总结 |
39 |
| - |
40 |
| -详解:博文 |
41 |
| - |
42 |
| -效果图: |
43 |
| - |
44 |
| - |
45 |
| - |
46 |
| - |
47 |
| - |
48 |
| - |
49 |
| - |
50 |
| -👣 基于AVPlayer自定义播放器 |
51 |
| - |
52 |
| -详解:博文 |
53 |
| - |
54 |
| -效果图: |
55 |
| - |
56 |
| - |
57 |
| - |
58 |
| - |
59 |
| - |
60 |
| - |
61 |
| - |
62 |
| - |
63 |
| -👣 给文本Label添加点击事件Block & Delegate 回调 |
64 |
| - |
65 |
| -详解:博文 |
66 |
| - |
67 |
| -效果图: |
68 |
| - |
69 |
| - |
70 |
| - |
71 |
| - |
72 |
| - |
73 |
| - |
74 |
| - |
75 |
| -👣 SQLite3 |
76 |
| - |
77 |
| -详解:博文 |
78 |
| - |
79 |
| -效果图: |
80 |
| - |
81 |
| - |
82 |
| - |
83 |
| - |
84 |
| - |
85 |
| - |
86 |
| - |
87 |
| - |
88 |
| -**未完.............待续** |
89 |
| - |
90 |
| - |
91 |
| - |
92 |
| - |
93 |
| - |
94 |
| - |
95 |
| - |
96 |
| - |
97 |
| - |
98 |
| - |
99 |
| - |
100 |
| - |
101 |
| - |
102 |
| - |
103 |
| - |
104 |
| - |
105 |
| - |
106 |
| - |
107 |
| - |
108 |
| - |
109 |
| - |
110 |
| - |
111 |
| - |
112 |
| - |
113 |
| - |
114 |
| - |
115 |
| - |
116 |
| - |
117 |
| - |
118 |
| - |
119 |
| - |
120 |
| - |
121 |
| - |
| 1 | +# Flutter 实现百姓生活 Lift+ |
| 2 | + |
| 3 | +使用 flutter 仿写 百姓生活Lift+ ,内部涉及 flutter 常用组件的使用示例和规范。 |
| 4 | +主要模块有:商城首页、商品分类、商品详情、购物车、个人中心等, |
| 5 | +主要用到的技术有:dio进行网络请求、fluro进行路由跳转、url_launcher进行打电话、shared_preferences进行数据存储、flutter_screenutil进行屏幕适配、Provide进行跨组件通信、flutter_html进行html的加载、flutter_easyrefresh进行列表的刷新等。 |
| 6 | + |
| 7 | +## 示例图 |
| 8 | + |
| 9 | + |
| 10 | + |
| 11 | + |
| 12 | +## Widget |
| 13 | + |
| 14 | +Flutter的理念是**万物皆Widget**(Everything is Widget), |
| 15 | +这是为了实现Flutter的一个设计理念:**激进式组合(Aggressive composability)**。 |
| 16 | +Widget由一系列的小的Widget组合而成,而这些进行组合的Widget,本身是由更基础的Widget构成。 |
| 17 | + |
| 18 | +Widget的定义是:**描述一个UI元素的配置数据。它并不是表示最终绘制在设备上的显示元素,而只是描述显示元素的一个配置数据**。 |
| 19 | +Widget主要分为三类:**Component Widget(*组合类Widget*)、Proxy Widget(*代理类Widget*)以及Render Widget(*渲染类Widget*)**, |
| 20 | +其中只有Render Widget才会参与后面的布局(layout)和渲染(paint)流程。 |
| 21 | + |
| 22 | +- **Widget是Element的配置数据,Element才真正代表屏幕显示元素;** |
| 23 | +- **一个Widget对象可以对应多个Element对象。** |
| 24 | + |
| 25 | +## Element |
| 26 | + |
| 27 | +- 维护Element Tree,根据Widget Tree的变化来更新Element Tree, |
| 28 | +包括:节点的插入、更新、删除、移动等; |
| 29 | +并起到纽带的作用,**将Widget以及RenderObject关联到Element Tree上**。 |
| 30 | +- Element分为**ComponentElement(组合类Element)和RenderObjectElement(渲染类Element)**, |
| 31 | + 前者负责组合子Element,后者负责渲染。 |
| 32 | + |
| 33 | +**Element有4种状态:initial(*初始状态*),active(*激活状态*),inactive(*未激活状态*),defunct(*失效状态*)** |
| 34 | + |
| 35 | +## RenderObject |
| 36 | + |
| 37 | +- RenderObject主要**负责绘制**`paint`,**布局**`layout`,**命中测试**`hitTest`等。 |
| 38 | +- RenderObject**布局的原则是,Constraints向下,Sizes向上,父节点设置本节点的位置**。 |
| 39 | +- RenderView是整个RenderObject Tree的根节点,其child是一个 **RenderBox 类型的RenderObject**。 |
| 40 | + |
| 41 | +## Platform Channel |
| 42 | + |
| 43 | +Flutter是通过Platform Channel同宿主平台进行通信的。 |
| 44 | +为了保证界面能够响应及时,消息的传递是异步的。 |
| 45 | +Flutter定义了三种不同类型的Platform Channel,它们分别是: |
| 46 | +- **BasicMessageChannel:用于传递字符串和半结构化的信息。支持数据双向传递,有返回值**。 |
| 47 | +- **MethodChannel:用于传递方法调用(method invocation)。支持数据双向传递,有返回值**。 |
| 48 | +- **EventChannel: 用于数据流/(事件流)(event streams)的通信,仅支持数据单向传递(从Platform 平台 到Flutter),无返回值**。 |
| 49 | + |
| 50 | +## Provide进行跨组件通信 |
| 51 | + |
| 52 | +在使用Provider的时候,我们主要关心三个概念: |
| 53 | + >ChangeNotifier:真正数据(状态)存放的地方 |
| 54 | + ChangeNotifierProvider:Widget树中提供数据(状态)的地方,会在其中创建对应的ChangeNotifier |
| 55 | + Consumer:Widget树中需要使用数据(状态)的地方 |
| 56 | + |
| 57 | +``` Swift |
| 58 | +void main() { |
| 59 | + //启动Flutter应用,runApp接受一个Widget参数,在本示例中它是一个MyApp对象,MyApp()是Flutter应用的根组件 |
| 60 | + var currentIndexProvide = CurrentIndexProvider(); |
| 61 | + |
| 62 | + //flutter_provide 状态管理 |
| 63 | + var providers = Providers(); |
| 64 | + providers |
| 65 | + ..provide(Provider<CurrentIndexProvider>.value(currentIndexProvide)) |
| 66 | + |
| 67 | + //ProviderNode封装了InheritWidget,并且提供了 一个providers容器用于放置状态。 |
| 68 | + runApp(ProviderNode(child: MyApp(),providers: providers)); |
| 69 | +} |
| 70 | + |
| 71 | + @override |
| 72 | + Widget build(BuildContext context) { |
| 73 | + ScreenUtil.instance = ScreenUtil(width: 750, height: 1334)..init(context); |
| 74 | + return Provide<CurrentIndexProvider> ( |
| 75 | + builder: (context,child,val) { |
| 76 | + //获取状态currentIndex |
| 77 | + // int currentIndex = val.currentIndex; 或者使用以下方式获取 currentIndex |
| 78 | + int currentIndex = Provide.value<CurrentIndexProvider>(context).currentIndex; |
| 79 | + //Scaffold 是 Material 库中提供的页面脚手架, |
| 80 | + //它提供了默认的导航栏、标题和包含主屏幕widget树(后同“组件树”或“部件树”)的body属性,组件树可以很复杂 |
| 81 | + return Scaffold( |
| 82 | + backgroundColor: Color.fromRGBO(244, 245, 245 ,1.0), |
| 83 | + bottomNavigationBar: BottomNavigationBar( |
| 84 | + type: BottomNavigationBarType.fixed, |
| 85 | + currentIndex: currentIndex, |
| 86 | + items: bottomTabs, |
| 87 | + onTap: (index) { |
| 88 | + //更改状态currentIndex |
| 89 | + Provide.value<CurrentIndexProvider>(context).changeIndex(index); |
| 90 | + }, |
| 91 | + ), |
| 92 | + //body的组件树中包含了一个Center 组件,Center 可以将其子组件树对齐到屏幕中心 |
| 93 | + body: IndexedStack( |
| 94 | + index: currentIndex, |
| 95 | + children: tabBodies, |
| 96 | + ), |
| 97 | + ); |
| 98 | + } |
| 99 | + ); |
| 100 | + } |
| 101 | + |
| 102 | +/* 作用:监听点击tabbar时,下标的改变*/ |
| 103 | + //ChangeNotifier,意思是可以不用管理听众 |
| 104 | +class CurrentIndexProvider with ChangeNotifier { |
| 105 | + int currentIndex = 0; |
| 106 | + changeIndex(int newIndex) { |
| 107 | + currentIndex = newIndex; |
| 108 | + print('点击的值'); |
| 109 | + print(newIndex); |
| 110 | + //通过notifyListeners可以通知听众刷新。 |
| 111 | + notifyListeners(); |
| 112 | + } |
| 113 | + |
| 114 | +} |
| 115 | + |
| 116 | +``` |
| 117 | + |
| 118 | +## Flutter 进行网络请求实现 |
| 119 | + |
| 120 | +``` Swift |
| 121 | + |
| 122 | +Future request(url,{formData})async |
| 123 | +{ |
| 124 | + try{ |
| 125 | + Response response; |
| 126 | + Dio dio = new Dio(); |
| 127 | + dio.options.contentType = Headers.formUrlEncodedContentType; |
| 128 | + if(formData == null) { |
| 129 | + response = await dio.post(servicePath[url]); |
| 130 | + } else { |
| 131 | + response = await dio.post(servicePath[url],data:formData); |
| 132 | + } |
| 133 | + print("查看响应数据请求url:${servicePath[url]},\n返回数据:${response.data}"); |
| 134 | + if (response.statusCode == 200) { |
| 135 | + return response.data; |
| 136 | + } else { |
| 137 | + throw Exception('有异常。。。'); |
| 138 | + } |
| 139 | + |
| 140 | + }catch(e){ |
| 141 | + return print('ERROR:======>$e'); |
| 142 | + } |
| 143 | + |
| 144 | +} |
| 145 | + |
| 146 | +``` |
0 commit comments