Skip to content
项目
群组
代码片段
帮助
当前项目
正在载入...
登录 / 注册
切换导航面板
F
flutter_clx_base
项目
项目
详情
活动
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
图表
比较
统计图
议题
0
议题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
日程
统计图
Wiki
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
图像
聊天
创建新问题
作业
提交
问题看板
Open sidebar
openSourceLibrary
flutter_clx_base
Commits
f05ef243
提交
f05ef243
authored
8月 09, 2022
作者:
guoqing
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
my listView
上级
c7d72281
显示空白字符变更
内嵌
并排
正在显示
2 个修改的文件
包含
351 行增加
和
0 行删除
+351
-0
my_refresh_list_public.dart
lib/widget/my_refresh_list_public.dart
+243
-0
state_layout.dart
lib/widget/state_layout.dart
+108
-0
没有找到文件。
lib/widget/my_refresh_list_public.dart
0 → 100644
浏览文件 @
f05ef243
import
'dart:io'
;
import
'package:flutter/cupertino.dart'
;
import
'package:flutter/material.dart'
;
import
'state_layout.dart'
;
/// 封装下拉刷新与加载更多
class
MyListViewPublic
extends
StatefulWidget
{
const
MyListViewPublic
(
{
Key
?
key
,
required
this
.
itemBuilder
,
required
this
.
requestData
,
this
.
pageSize
=
10
,
this
.
padding
,
this
.
itemExtent
,
this
.
controller
,
this
.
onRefresh
,
this
.
canLoadMore
=
true
,
this
.
firstRefresh
=
true
,
this
.
emptyText
})
:
super
(
key:
key
);
final
bool
canLoadMore
;
//是否允许上拉
final
ItemBuilder
itemBuilder
;
final
MyListController
?
controller
;
final
bool
firstRefresh
;
final
String
?
emptyText
;
//(page, pageSize,_requestSuccess,_requestError){}
final
RequestDataCallback
requestData
;
/// 一页的数量,默认为10
final
int
pageSize
;
/// padding属性使用时注意会破坏原有的SafeArea,需要自行计算bottom大小
final
EdgeInsetsGeometry
?
padding
;
final
double
?
itemExtent
;
final
Function
?
onRefresh
;
@override
State
<
MyListViewPublic
>
createState
()
=>
_MyListViewPublicState
();
}
typedef
RefreshCallback
=
Future
<
void
>
Function
();
typedef
LoadMoreCallback
=
Future
<
void
>
Function
();
typedef
SuccessCallback
=
Function
(
List
list
);
typedef
RequestDataCallback
=
Function
(
int
page
,
int
pageSize
,
SuccessCallback
success
,
Function
error
);
typedef
ItemBuilder
=
Function
(
BuildContext
context
,
int
index
,
dynamic
item
);
class
_MyListViewPublicState
extends
State
<
MyListViewPublic
>
{
/// 是否正在加载数据
bool
_isLoading
=
false
;
int
page
=
1
;
StateType
stateType
=
StateType
.
loading
;
int
listItemCount
=
0
;
bool
hasMore
=
true
;
final
List
<
dynamic
>
_dataList
=
[];
@override
void
initState
()
{
if
(
widget
.
firstRefresh
)
{
stateType
=
StateType
.
loading
;
//第一次直接获取数据
_defaultRefresh
();
}
else
{
stateType
=
StateType
.
success
;
}
super
.
initState
();
}
@override
void
didChangeDependencies
()
{
//绑定控制器
if
(
widget
.
controller
!=
null
)
{
widget
.
controller
?.
_bindEasyRefreshState
(
this
);
}
super
.
didChangeDependencies
();
}
void
callRefresh
()
{
_defaultRefresh
();
}
@override
Widget
build
(
BuildContext
context
)
{
Widget
child
=
RefreshIndicator
(
onRefresh:
_defaultRefresh
,
child:
listItemCount
==
0
?
StateLayout
(
type:
stateType
,
hintText:
widget
.
emptyText
,
)
:
ScrollConfiguration
(
//取消列表滑动水波纹
behavior:
MyBehavior
(),
child:
ListView
.
builder
(
itemCount:
!
widget
.
canLoadMore
?
listItemCount
:
listItemCount
+
1
,
padding:
widget
.
padding
,
itemExtent:
widget
.
itemExtent
,
itemBuilder:
(
BuildContext
context
,
int
index
)
{
/// 不需要加载更多则不需要添加FootView
if
(!
widget
.
canLoadMore
)
{
return
widget
.
itemBuilder
(
context
,
index
,
_dataList
[
index
]);
}
else
{
return
index
<
listItemCount
?
widget
.
itemBuilder
(
context
,
index
,
_dataList
[
index
])
:
MoreWidget
(
listItemCount
,
hasMore
,
widget
.
pageSize
);
}
},
),
),
);
return
SafeArea
(
child:
NotificationListener
(
onNotification:
(
ScrollNotification
note
)
{
/// 确保是垂直方向滚动,且滑动至底部
if
(
note
.
metrics
.
pixels
==
note
.
metrics
.
maxScrollExtent
&&
note
.
metrics
.
axis
==
Axis
.
vertical
)
{
_loadMore
();
}
return
true
;
},
child:
child
,
),
);
}
Future
<
void
>
_defaultRefresh
()
async
{
widget
.
onRefresh
?.
call
();
page
=
1
;
_dataList
.
clear
();
listItemCount
=
0
;
stateType
=
StateType
.
loading
;
await
widget
.
requestData
(
page
,
widget
.
pageSize
,
_requestSuccess
,
_requestError
);
}
Future
<
void
>
_defaultLoadMore
()
async
{
page
++;
await
widget
.
requestData
(
page
,
widget
.
pageSize
,
_requestSuccess
,
_requestError
);
}
void
_requestSuccess
(
List
?
result
)
{
result
??=
[];
_dataList
.
addAll
(
result
);
listItemCount
=
_dataList
.
length
;
hasMore
=
result
.
length
==
widget
.
pageSize
;
if
(
page
==
1
&&
(
result
.
length
==
0
))
{
stateType
=
StateType
.
empty
;
//显示空布局
}
else
{
stateType
=
StateType
.
success
;
//显示成功布局
}
_isLoading
=
false
;
setState
(()
{});
}
void
_requestError
(
r
)
{
stateType
=
StateType
.
error
;
//显示异常布局
}
Future
<
void
>
_loadMore
()
async
{
if
(!
widget
.
canLoadMore
)
{
return
;
}
if
(
_isLoading
)
{
return
;
}
if
(!
hasMore
)
{
return
;
}
_isLoading
=
true
;
await
_defaultLoadMore
();
}
}
class
MyListController
{
late
_MyListViewPublicState
_deerListViewState
;
// 绑定状态
void
_bindEasyRefreshState
(
_MyListViewPublicState
state
)
{
_deerListViewState
=
state
;
}
//刷新
void
callRefresh
()
{
_deerListViewState
.
callRefresh
();
}
}
class
MoreWidget
extends
StatelessWidget
{
const
MoreWidget
(
this
.
itemCount
,
this
.
hasMore
,
this
.
pageSize
,
{
Key
?
key
,
})
:
super
(
key:
key
);
final
int
itemCount
;
final
bool
hasMore
;
final
int
pageSize
;
@override
Widget
build
(
BuildContext
context
)
{
TextStyle
style
=
const
TextStyle
(
color:
Color
(
0x8A000000
));
return
Padding
(
padding:
const
EdgeInsets
.
symmetric
(
vertical:
10.0
),
child:
Row
(
mainAxisAlignment:
MainAxisAlignment
.
center
,
crossAxisAlignment:
CrossAxisAlignment
.
center
,
children:
<
Widget
>[
hasMore
?
const
CupertinoActivityIndicator
()
:
const
SizedBox
(),
hasMore
?
const
SizedBox
(
width:
5
,
)
:
const
SizedBox
(),
/// 只有一页的时候,就不显示FooterView了
Text
(
hasMore
?
'正在加载中...'
:
(
itemCount
<
pageSize
?
''
:
'没有了呦~'
),
style:
style
),
],
),
);
}
}
//取消列表滑动水波纹
class
MyBehavior
extends
ScrollBehavior
{
@override
Widget
buildOverscrollIndicator
(
BuildContext
context
,
Widget
child
,
ScrollableDetails
details
)
{
if
(
Platform
.
isAndroid
||
Platform
.
isFuchsia
)
{
return
child
;
}
else
{
return
super
.
buildOverscrollIndicator
(
context
,
child
,
details
);
}
}
}
lib/widget/state_layout.dart
0 → 100644
浏览文件 @
f05ef243
import
'package:flutter/cupertino.dart'
;
import
'package:flutter/material.dart'
;
import
'../utils/image_utils.dart'
;
class
StateLayout
extends
StatefulWidget
{
const
StateLayout
({
Key
?
key
,
required
this
.
type
,
this
.
hintText
})
:
super
(
key:
key
);
final
StateType
type
;
final
String
?
hintText
;
@override
State
<
StateLayout
>
createState
()
=>
_StateLayoutState
();
}
class
_StateLayoutState
extends
State
<
StateLayout
>
{
@override
Widget
build
(
BuildContext
context
)
{
return
SingleChildScrollView
(
child:
SizedBox
(
height:
MediaQuery
.
of
(
context
).
size
.
height
-
30.0
,
child:
widget
.
type
==
StateType
.
loading
?
_loadingWidget
()
:
_otherWidget
(),
),
);
}
Widget
_loadingWidget
()
{
return
Column
(
crossAxisAlignment:
CrossAxisAlignment
.
center
,
mainAxisAlignment:
MainAxisAlignment
.
center
,
children:
const
[
CupertinoActivityIndicator
(
radius:
16.0
),
SizedBox
(
width:
double
.
infinity
,
height:
16.0
,
),
SizedBox
(
height:
50
,
),
],
);
}
Widget
_otherWidget
()
{
switch
(
widget
.
type
)
{
case
StateType
.
network
:
return
_buildNormalView
(
'icon_no_wifi'
,
'无网络连接'
);
case
StateType
.
loading
:
return
Container
();
case
StateType
.
empty
:
return
_buildNormalView
(
'icon_empty'
,
widget
.
hintText
??
'暂无数据'
);
case
StateType
.
error
:
return
_buildNormalView
(
'icon_list_failure'
,
'请求失败,请重试'
);
case
StateType
.
success
:
return
Container
();
}
}
Widget
_buildNormalView
(
String
img
,
String
hintText
)
{
return
Column
(
crossAxisAlignment:
CrossAxisAlignment
.
center
,
mainAxisAlignment:
MainAxisAlignment
.
center
,
children:
<
Widget
>[
Opacity
(
opacity:
1
,
child:
Container
(
height:
120.0
,
width:
120.0
,
decoration:
BoxDecoration
(
image:
DecorationImage
(
image:
ImageUtils
.
getAssetImage
(
img
),
),
),
)),
const
SizedBox
(
width:
double
.
infinity
,
height:
16.0
,
),
Text
(
hintText
,
style:
const
TextStyle
(
fontSize:
14
,
color:
Colors
.
grey
),
),
const
SizedBox
(
height:
50
,
),
],
);
}
}
enum
StateType
{
/// 无网络
network
,
/// 加载中
loading
,
/// 空
empty
,
///异常
error
,
///成功
success
}
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论