網站首頁 編程語言 正文
前言
在此之前對列表下拉刷新做了調整方案,具體介紹可以閱讀下拉刷新組件交互調整。既然列表有下拉刷新外當然還有上拉加載更多操作了,本次就來介紹如何為列表增加上拉加載更多的交互實現。
實現方案
上拉刷新實現形式上可以有多種實現方式,若不帶交互形式可采用NotificationListener
組件監聽滑動來實現上拉加載更多;如果對操作交互上有一定要求期望上拉刷新帶有直觀動畫可操作性就需要實現一定樣式來實現了。
監聽NotificationListener實現
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調整
BouncingScrollPhysics
是iOS
帶有阻尼效果滑動交互,在下拉刷新中帶有回彈阻尼效果是比較好的交互,但在上拉加載更多獲取交互上這種效果或許有點多余。因此需要定制下拉刷新帶有回彈阻尼效果,上拉加載沒有回彈阻尼效果的。ScrollPhysics
CustomScrollView( physics: BouncingScrollPhysics(), slivers: <Widget>[] )
具體實現代碼如下所示:
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); /// 阻尼參數計算 @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; } /// 邊界條件 復用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; }
但是直接會發生錯誤日志,由于回調中OverscrollIndicatorNotification
是沒有metrics
對象。對于
The following NoSuchMethodError was thrown while notifying listeners for AnimationController: Class 'OverscrollIndicatorNotification' has no instance getter 'metrics'.
由于上滑沒有阻尼滑動到底部回調Notification
發生了變化,因此需要在NotificationListener
中增加判斷對超出滑動范圍回調進行過濾處理避免異常情況發生。
if(scrollNotification is OverscrollIndicatorNotification){ return false; }
結果展示
演示代碼看這里
原文鏈接:https://juejin.cn/post/7136948689628561444
相關推薦
- 2022-09-16 Numpy中的shape、reshape函數的區別_python
- 2022-07-16 mac拷貝文件到Linux服務器、運行jar包,以及常用為Linux文件操作命令
- 2023-11-18 數據處理使用Python提取String、字符串中的數字
- 2022-08-19 Spring Cloud Config配置服務
- 2022-04-27 C語言陷阱與缺陷之數組越界訪問詳解_C 語言
- 2022-05-18 Python學習之自定義異常詳解_python
- 2023-04-19 Element UI Table常用使用方法(header-cell-style;表頭中的全選框取消
- 2022-11-13 Git如何實現checkout遠程tag_相關技巧
- 最近更新
-
- window11 系統安裝 yarn
- 超詳細win安裝深度學習環境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權
- redisson分布式鎖中waittime的設
- maven:解決release錯誤:Artif
- restTemplate使用總結
- Spring Security之安全異常處理
- MybatisPlus優雅實現加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務發現-Nac
- Spring Security之基于HttpR
- Redis 底層數據結構-簡單動態字符串(SD
- arthas操作spring被代理目標對象命令
- Spring中的單例模式應用詳解
- 聊聊消息隊列,發送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支