Skip to content

Commit ffb91bf

Browse files
CoderLNHuiGitHubIdea
authored andcommitted
no message
1 parent bc227ef commit ffb91bf

File tree

1 file changed

+146
-121
lines changed

1 file changed

+146
-121
lines changed

README.md

Lines changed: 146 additions & 121 deletions
Original file line numberDiff line numberDiff line change
@@ -1,121 +1,146 @@
1-
##
2-
3-
>本仓库将会持续更新一些「小的功能模块,实现思路」 ,重点是怎么一步步抽取封装
4-
5-
6-
## Function module
7-
8-
👣 新闻滚动条 11 22
9-
10-
详解:博文
11-
12-
效果图:
13-
![封装新闻滚动条.gif](http://upload-images.jianshu.io/upload_images/2230763-352aa142cc6cf27d.gif?imageMogr2/auto-orient/strip)
14-
15-
16-
17-
👣 循环利用tableView
18-
19-
详解:博文
20-
21-
效果图:
22-
23-
![循环利用tableView.gif](http://upload-images.jianshu.io/upload_images/2230763-218adbdf88a41ffb.gif?imageMogr2/auto-orient/strip)
24-
25-
26-
27-
👣 无限轮播实现(3张 || 2张)
28-
29-
详解:博文
30-
31-
32-
效果图:
33-
34-
![无限轮播.gif](http://upload-images.jianshu.io/upload_images/2230763-b350042656f41294.gif?imageMogr2/auto-orient/strip)
35-
36-
37-
38-
👣 Masonry使用总结
39-
40-
详解:博文
41-
42-
效果图:
43-
44-
45-
![Masonry常用效果图.gif](http://upload-images.jianshu.io/upload_images/2230763-4565ab5938e96b5c.gif?imageMogr2/auto-orient/strip)
46-
47-
48-
49-
50-
👣 基于AVPlayer自定义播放器
51-
52-
详解:博文
53-
54-
效果图:
55-
56-
57-
![AVPlayer自定义播放器.gif](http://upload-images.jianshu.io/upload_images/2230763-67593444d7b59251.gif?imageMogr2/auto-orient/strip)
58-
59-
60-
61-
62-
63-
👣 给文本Label添加点击事件Block & Delegate 回调
64-
65-
详解:博文
66-
67-
效果图:
68-
69-
70-
![LNAttributeTapLabel.gif](http://upload-images.jianshu.io/upload_images/2230763-1d8ed8cc36a11e6e.gif?imageMogr2/auto-orient/strip)
71-
72-
73-
74-
75-
👣 SQLite3
76-
77-
详解:博文
78-
79-
效果图:
80-
81-
82-
![SQLite3.gif](http://upload-images.jianshu.io/upload_images/2230763-96e2bebc2cbf811f.gif?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
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+
![FlutterProject](https://cdn.jsdelivr.net/gh/SunHui-Candy/Simg@tc/22img/FlutterProject.gif)
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

Comments
 (0)