Skip to content

Commit c2aaf33

Browse files
committed
项目页增加下拉刷新、加载更多逻辑
1 parent d3ea546 commit c2aaf33

File tree

3 files changed

+123
-69
lines changed

3 files changed

+123
-69
lines changed

lib/http/api.dart

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -180,8 +180,9 @@ class ProjectApi {
180180
static String PROJECT_LIST(int page, int id) =>
181181
'/project/list/$page/json?cid=$id';
182182

183+
//页码从1开始
183184
static Future<Response> getNewProjects(int page) {
184-
//老接口原因,输入页码从0开始
185+
//老接口原因,实际输入页码是从0开始
185186
return dio.get(NEW_PROJECTS(page - 1));
186187
}
187188

lib/page/home/project/project_page.dart

Lines changed: 119 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import 'package:cached_network_image/cached_network_image.dart';
2+
import 'package:flutter/cupertino.dart';
23
import 'package:flutter/material.dart';
34
import 'package:flutter_bloc/flutter_bloc.dart';
45
import 'package:flutter_swiper/flutter_swiper.dart';
@@ -28,10 +29,16 @@ class _ProjectSubPageState extends State<ProjectSubPage>
2829
List<BannerEntity> banners;
2930
List<ProjectTypeEntity> projectTypes;
3031
List<ProjectEntity> projectDatas;
32+
ScrollController _scrollController;
33+
int currentProjectPage;
34+
int totalProjectPage;
35+
bool isLoading = false;
36+
GlobalKey<RefreshIndicatorState> refreshKey;
3137

3238
@override
3339
void initState() {
3440
super.initState();
41+
refreshKey = GlobalKey();
3542
projectBloc = ProjectBloc(BlocProvider.of<HomeBloc>(context));
3643
banners ??= [];
3744
projectTypes ??= [
@@ -81,20 +88,41 @@ class _ProjectSubPageState extends State<ProjectSubPage>
8188
ProjectTypeEntity.t(1, '1开发模式'),
8289
];
8390
projectDatas ??= [];
84-
t();
91+
currentProjectPage ??= 1;
92+
totalProjectPage ??= 1;
93+
_scrollController ??= ScrollController();
94+
_scrollController.addListener(() {
95+
// 如果下拉的当前位置到scroll的最下面
96+
if (_scrollController.position.pixels ==
97+
_scrollController.position.maxScrollExtent) {
98+
if (currentProjectPage < totalProjectPage && !isLoading) {
99+
t(currentProjectPage + 1);
100+
}
101+
}
102+
});
103+
t(currentProjectPage);
85104
}
86105

87-
Future t() async {
106+
Future t(int page) async {
107+
isLoading = true;
88108
await Future.delayed(Duration(seconds: 2));
89-
Response res =
90-
await dio.get('https://www.wanandroid.com/article/listproject/0/json');
109+
Response res = await ProjectApi.getNewProjects(page);
91110
await dio.get('https://www.wanandroid.com/lg/collect/list/0/json');
92111
BaseEntity baseEntity = BaseEntity.fromJson(res.data);
93112
BaseListEntity<List> baseListEntity =
94113
BaseListEntity.fromJson(baseEntity.data);
95-
projectDatas = baseListEntity.datas.map((json) {
96-
return ProjectEntity.fromJson(json);
97-
}).toList();
114+
currentProjectPage = baseListEntity.curPage;
115+
totalProjectPage = baseListEntity.pageCount;
116+
if (projectDatas == null || projectDatas.length == 0) {
117+
projectDatas = baseListEntity.datas.map((json) {
118+
return ProjectEntity.fromJson(json);
119+
}).toList();
120+
} else {
121+
projectDatas.addAll(baseListEntity.datas.map((json) {
122+
return ProjectEntity.fromJson(json);
123+
}).toList());
124+
}
125+
isLoading = false;
98126
setState(() {});
99127
}
100128

@@ -127,69 +155,92 @@ class _ProjectSubPageState extends State<ProjectSubPage>
127155
child: BlocBuilder<ProjectEvent, ProjectState>(
128156
bloc: projectBloc,
129157
builder: (context, state) {
130-
return CustomScrollView(
131-
physics: AlwaysScrollableScrollPhysics(
132-
parent: BouncingScrollPhysics()),
133-
slivers: <Widget>[
134-
SliverToBoxAdapter(
135-
child: bannerView(
136-
datas: banners.map((entity) {
137-
return BannerModel(
138-
entity.title ?? '',
139-
entity.imagePath ?? '',
140-
entity.url ?? '',
141-
);
142-
}).toList()),
143-
),
144-
SliverToBoxAdapter(
145-
child: typesGridView(
146-
datas: projectTypes
147-
.asMap()
148-
.map<int, ProjectTypesModel>((index, entity) {
149-
return MapEntry(
150-
index,
151-
ProjectTypesModel(
152-
entity.id,
153-
entity.name,
154-
Image.asset(
155-
MyImage.animals[index % MyImage.animals.length],
156-
width: pt(40),
157-
height: pt(40),
158+
return RefreshIndicator(
159+
key: refreshKey,
160+
color: WColors.theme_color,
161+
onRefresh: ()async{
162+
//todo 在bloc模式里这里该怎么做?如何弄一个可以自己控制阻塞、完成的future对象?
163+
await Future.delayed(Duration(seconds: 2));
164+
},
165+
child: CustomScrollView(
166+
controller: _scrollController,
167+
physics: AlwaysScrollableScrollPhysics(
168+
parent: BouncingScrollPhysics()),
169+
slivers: <Widget>[
170+
SliverToBoxAdapter(
171+
child: bannerView(
172+
datas: banners.map((entity) {
173+
return BannerModel(
174+
entity.title ?? '',
175+
entity.imagePath ?? '',
176+
entity.url ?? '',
177+
);
178+
}).toList()),
179+
),
180+
SliverToBoxAdapter(
181+
child: typesGridView(
182+
datas: projectTypes
183+
.asMap()
184+
.map<int, ProjectTypesModel>((index, entity) {
185+
return MapEntry(
186+
index,
187+
ProjectTypesModel(
188+
entity.id,
189+
entity.name,
190+
Image.asset(
191+
MyImage.animals[index % MyImage.animals.length],
192+
width: pt(40),
193+
height: pt(40),
194+
),
158195
),
159-
),
160-
);
161-
})
162-
.values
163-
.toList(),
196+
);
197+
})
198+
.values
199+
.toList(),
200+
),
164201
),
165-
),
166-
SliverToBoxAdapter(
167-
child: Container(
168-
color: WColors.gray_background,
169-
padding: EdgeInsets.only(left: pt(16), top: pt(8)),
170-
child: Row(
171-
children: <Widget>[
172-
Image.asset(
173-
'images/new.png',
174-
width: pt(30),
175-
height: pt(30),
176-
),
177-
SizedBox(
178-
width: pt(10),
179-
),
180-
Text(
181-
res.newestProject,
182-
style: TextStyle(
183-
color: Colors.black,
184-
fontSize: 17,
185-
fontWeight: FontWeight.bold),
186-
)
187-
],
202+
SliverToBoxAdapter(
203+
child: Container(
204+
color: WColors.gray_background,
205+
padding: EdgeInsets.only(left: pt(16), top: pt(8)),
206+
child: Row(
207+
children: <Widget>[
208+
Image.asset(
209+
'images/new.png',
210+
width: pt(30),
211+
height: pt(30),
212+
),
213+
SizedBox(
214+
width: pt(10),
215+
),
216+
Text(
217+
res.newestProject,
218+
style: TextStyle(
219+
color: Colors.black,
220+
fontSize: 17,
221+
fontWeight: FontWeight.bold),
222+
)
223+
],
224+
),
188225
),
189226
),
190-
),
191-
projectGrid(datas: projectDatas),
192-
],
227+
projectGrid(datas: projectDatas),
228+
SliverToBoxAdapter(
229+
child: Container(
230+
width: double.infinity,
231+
height: pt(45),
232+
color: WColors.gray_background,
233+
alignment: Alignment.center,
234+
child: (currentProjectPage < totalProjectPage)
235+
? CupertinoActivityIndicator()
236+
: Text(
237+
res.isBottomst,
238+
style: TextStyle(color: WColors.hint_color),
239+
),
240+
),
241+
),
242+
],
243+
),
193244
);
194245
},
195246
),
@@ -444,7 +495,7 @@ class _ProjectSubPageState extends State<ProjectSubPage>
444495
child: GestureDetector(
445496
onTap: () {
446497
print('click item');
447-
t();
498+
refreshKey.currentState.show();
448499
},
449500
child: Column(
450501
crossAxisAlignment: CrossAxisAlignment.start,
@@ -530,7 +581,7 @@ class _ProjectSubPageState extends State<ProjectSubPage>
530581
Icon(
531582
Icons.chevron_right,
532583
color: WColors.hint_color_dark,
533-
size: pt(10),
584+
size: pt(12),
534585
),
535586
Expanded(
536587
child: Align(

lib/page/todo/todo_list.dart

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,8 +99,10 @@ class _TodoListPageState extends State<TodoListPage> {
9999
}
100100
return true;
101101
}
102+
return false;
102103
},
103104
//todo 如何用代码控制RefreshIndicator拉出刷新头?
105+
//答 用“RefreshIndicatorState“
104106
child: RefreshIndicator(
105107
color: WColors.theme_color,
106108
child: ListView.builder(

0 commit comments

Comments
 (0)