Android Flutter實(shí)現(xiàn)上拉加載組件的示例代碼
前言
在此之前對(duì)列表下拉刷新做了調(diào)整方案,具體介紹可以閱讀下拉刷新組件交互調(diào)整。既然列表有下拉刷新外當(dāng)然還有上拉加載更多操作了,本次就來介紹如何為列表增加上拉加載更多的交互實(shí)現(xiàn)。
實(shí)現(xiàn)方案
上拉刷新實(shí)現(xiàn)形式上可以有多種實(shí)現(xiàn)方式,若不帶交互形式可采用NotificationListener組件監(jiān)聽滑動(dòng)來實(shí)現(xiàn)上拉加載更多;如果對(duì)操作交互上有一定要求期望上拉刷新帶有直觀動(dòng)畫可操作性就需要實(shí)現(xiàn)一定樣式來實(shí)現(xiàn)了。
監(jiān)聽NotificationListener實(shí)現(xiàn)
NotificationListener(
onNotification: (scrollNotification) {
if (scrollNotification.metrics.pixels >=
scrollNotification.metrics.maxScrollExtent - size.height &&
scrollNotification.depth == 0) {
if (!isLoading) {
isLoading = true;
Future.delayed(Duration(seconds: 1), () {
isLoading = false;
length += 10;
Scaffold.of(context).showSnackBar(SnackBar(
content: Text('下拉加載更多了!??!'),
duration: Duration(milliseconds: 700),
));
setState(() {});
});
}
}
return false;
}
......
)NotificationListener增加樣式
SliverToBoxAdapter(
child: Center(
child: Text(
length < 30 ? "加載更多...." : "沒有更多",
style: TextStyle(fontSize: 25),
),
),
)ScrollPhysics調(diào)整

BouncingScrollPhysics是iOS帶有阻尼效果滑動(dòng)交互,在下拉刷新中帶有回彈阻尼效果是比較好的交互,但在上拉加載更多獲取交互上這種效果或許有點(diǎn)多余。因此需要定制下拉刷新帶有回彈阻尼效果,上拉加載沒有回彈阻尼效果的。ScrollPhysics
CustomScrollView( physics: BouncingScrollPhysics(), slivers: <Widget>[] )
具體實(shí)現(xiàn)代碼如下所示:
class CustomBouncingScrollPhysics extends ScrollPhysics {
const CustomBouncingScrollPhysics({ ScrollPhysics parent }) : super(parent: parent);
@override
CustomBouncingScrollPhysics applyTo(ScrollPhysics ancestor) {
return CustomBouncingScrollPhysics(parent: buildParent(ancestor));
}
double frictionFactor(double overscrollFraction) => 0.52 * math.pow(1 - overscrollFraction, 2);
/// 阻尼參數(shù)計(jì)算
@override
double applyPhysicsToUserOffset(ScrollMetrics position, double offset) {
assert(offset != 0.0);
assert(position.minScrollExtent <= position.maxScrollExtent);
if (!position.outOfRange)
return offset;
final double overscrollPastStart = math.max(position.minScrollExtent - position.pixels, 0.0);
final double overscrollPastEnd = math.max(position.pixels - position.maxScrollExtent, 0.0);
final double overscrollPast = math.max(overscrollPastStart, overscrollPastEnd);
final bool easing = (overscrollPastStart > 0.0 && offset < 0.0)
|| (overscrollPastEnd > 0.0 && offset > 0.0);
final double friction = easing
// Apply less resistance when easing the overscroll vs tensioning.
? frictionFactor((overscrollPast - offset.abs()) / position.viewportDimension)
: frictionFactor(overscrollPast / position.viewportDimension);
final double direction = offset.sign;
return direction * _applyFriction(overscrollPast, offset.abs(), friction);
}
static double _applyFriction(double extentOutside, double absDelta, double gamma) {
assert(absDelta > 0);
double total = 0.0;
if (extentOutside > 0) {
final double deltaToLimit = extentOutside / gamma;
if (absDelta < deltaToLimit)
return absDelta * gamma;
total += extentOutside;
absDelta -= deltaToLimit;
}
return total + absDelta;
}
/// 邊界條件 復(fù)用ClampingScrollPhysics的方法 保留列表在底部的邊界判斷條件
@override
double applyBoundaryConditions(ScrollMetrics position, double value){
if (position.maxScrollExtent <= position.pixels && position.pixels < value) // overscroll
return value - position.pixels;
if (position.pixels < position.maxScrollExtent && position.maxScrollExtent < value) // hit bottom edge
return value - position.maxScrollExtent;
return 0.0;
}
@override
Simulation createBallisticSimulation(ScrollMetrics position, double velocity) {
final Tolerance tolerance = this.tolerance;
if (velocity.abs() >= tolerance.velocity || position.outOfRange) {
return BouncingScrollSimulation(
spring: spring,
position: position.pixels,
velocity: velocity * 0.91, // TODO(abarth): We should move this constant closer to the drag end.
leadingExtent: position.minScrollExtent,
trailingExtent: position.maxScrollExtent,
tolerance: tolerance,
);
}
return null;
}
@override
double get minFlingVelocity => kMinFlingVelocity * 2.0;
@override
double carriedMomentum(double existingVelocity) {
return existingVelocity.sign *
math.min(0.000816 * math.pow(existingVelocity.abs(), 1.967).toDouble(), 40000.0);
}
@override
double get dragStartDistanceMotionThreshold => 3.5;
}但是直接會(huì)發(fā)生錯(cuò)誤日志,由于回調(diào)中OverscrollIndicatorNotification是沒有metrics對(duì)象。對(duì)于
The following NoSuchMethodError was thrown while notifying listeners for AnimationController: Class 'OverscrollIndicatorNotification' has no instance getter 'metrics'.
由于上滑沒有阻尼滑動(dòng)到底部回調(diào)Notification發(fā)生了變化,因此需要在NotificationListener中增加判斷對(duì)超出滑動(dòng)范圍回調(diào)進(jìn)行過濾處理避免異常情況發(fā)生。
if(scrollNotification is OverscrollIndicatorNotification){
return false;
}結(jié)果展示

以上就是Android Flutter實(shí)現(xiàn)上拉加載組件的示例代碼的詳細(xì)內(nèi)容,更多關(guān)于Android Flutter上拉加載的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
Android 自定義dialog的實(shí)現(xiàn)代碼
這篇文章主要介紹了Android 自定義dialog的實(shí)現(xiàn)代碼的相關(guān)資料,需要的朋友可以參考下2017-03-03
Android項(xiàng)目遷移到AndroidX的方法步驟
這篇文章主要介紹了Android項(xiàng)目遷移到AndroidX的方法步驟,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2019-12-12
Android實(shí)現(xiàn)阿里云oss上傳流程解析
這篇文章主要介紹了Android實(shí)現(xiàn)阿里云oss上傳流程解析,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-09-09
Android之FanLayout制作圓弧滑動(dòng)效果
這篇文章主要介紹了Android之FanLayout制作圓弧滑動(dòng)效果,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2021-08-08
一文教你如何使用Databinding寫一個(gè)關(guān)注功能
這篇文章主要介紹了一文教你如何使用Databinding寫一個(gè)關(guān)注功能,文章圍繞主題展開詳細(xì)的內(nèi)容介紹,具有一定的參考價(jià)值,需要的小伙伴可以參考一下2022-09-09
Android View事件分發(fā)和消費(fèi)源碼簡(jiǎn)單理解
這篇文章主要介紹了Android View事件分發(fā)和消費(fèi)源碼簡(jiǎn)單理解的相關(guān)資料,需要的朋友可以參考下2017-07-07
Android studio設(shè)置文件頭定制代碼注釋的方法
這篇文章主要介紹了Android studio設(shè)置文件頭定制代碼注釋的方法,非常不錯(cuò),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2018-08-08
AndroidStudio集成OpenCV的實(shí)現(xiàn)教程
本文主要介紹了Android?Studio集成OpenCV的實(shí)現(xiàn)教程,文中通過圖文介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-12-12
android編程實(shí)現(xiàn)局部界面動(dòng)態(tài)切換的方法
這篇文章主要介紹了android編程實(shí)現(xiàn)局部界面動(dòng)態(tài)切換的方法,以實(shí)例形式較為詳細(xì)的分析了Android局部切換的布局及功能實(shí)現(xiàn)技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下2015-11-11

