Skip to content

Commit ad145e2

Browse files
committed
增加下拉刷新效果
1 parent 354ea26 commit ad145e2

File tree

4 files changed

+128
-3
lines changed

4 files changed

+128
-3
lines changed

lib/page/dynamic_page.dart

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,8 +35,8 @@ class _DynamicPageState extends State<DynamicPage>
3535
showRefreshLoading() {
3636
///直接触发下拉
3737
new Future.delayed(const Duration(milliseconds: 500), () {
38-
scrollController.animateTo(-100,
39-
duration: Duration(milliseconds: 500), curve: Curves.linear);
38+
scrollController.animateTo(-141,
39+
duration: Duration(milliseconds: 600), curve: Curves.linear);
4040
return true;
4141
});
4242
}

lib/widget/gsy_pull_new_load_widget.dart

Lines changed: 125 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,13 @@
1+
import 'package:flare_flutter/flare_actor.dart';
12
import 'package:flutter/cupertino.dart' as IOS;
23
import 'package:flutter/material.dart';
34
import 'package:flutter_spinkit/flutter_spinkit.dart';
45
import 'package:gsy_github_app_flutter/common/style/gsy_style.dart';
56
import 'package:gsy_github_app_flutter/common/utils/common_utils.dart';
7+
import 'dart:math';
8+
9+
const double iosRefreshHeight = 140;
10+
const double iosRefreshIndicatorExtent = 100;
611

712
///通用下上刷新控件
813
class GSYPullLoadWidget extends StatefulWidget {
@@ -172,14 +177,18 @@ class _GSYPullLoadWidgetState extends State<GSYPullLoadWidget> {
172177
///用ios模式的下拉刷新
173178
return CustomScrollView(
174179
controller: _scrollController,
180+
175181
///回弹效果
176-
physics: const BouncingScrollPhysics(
182+
physics: const CustomBouncingScrollPhysics(
177183
parent: AlwaysScrollableScrollPhysics(),
178184
),
179185
slivers: <Widget>[
180186
///控制显示刷新的 CupertinoSliverRefreshControl
181187
IOS.CupertinoSliverRefreshControl(
188+
refreshIndicatorExtent: iosRefreshIndicatorExtent,
189+
refreshTriggerPullDistance: iosRefreshHeight,
182190
onRefresh: handleRefresh,
191+
builder: buildSimpleRefreshIndicator,
183192
),
184193
SliverSafeArea(
185194
sliver: SliverList(
@@ -276,6 +285,28 @@ class _GSYPullLoadWidgetState extends State<GSYPullLoadWidget> {
276285
),
277286
);
278287
}
288+
289+
Widget buildSimpleRefreshIndicator(
290+
BuildContext context,
291+
IOS.RefreshIndicatorMode refreshState,
292+
double pulledExtent,
293+
double refreshTriggerPullDistance,
294+
double refreshIndicatorExtent,
295+
) {
296+
return Align(
297+
alignment: Alignment.bottomCenter,
298+
child: new Container(
299+
color: Colors.black,
300+
width: MediaQuery.of(context).size.width,
301+
///动态大小处理
302+
height: pulledExtent > iosRefreshHeight ? pulledExtent : iosRefreshHeight,
303+
child: FlareActor("static/file/loading_world_now.flr",
304+
alignment: Alignment.topCenter,
305+
fit: BoxFit.cover,
306+
animation: "Earth Moving"),
307+
),
308+
);
309+
}
279310
}
280311

281312
class GSYPullLoadWidgetControl extends ChangeNotifier {
@@ -322,3 +353,96 @@ class GSYPullLoadWidgetControl extends ChangeNotifier {
322353
///是否加载中
323354
bool isLoading = false;
324355
}
356+
357+
///自定义弹性滑动模块
358+
class CustomBouncingScrollPhysics extends ScrollPhysics {
359+
const CustomBouncingScrollPhysics({ScrollPhysics parent})
360+
: super(parent: parent);
361+
362+
@override
363+
CustomBouncingScrollPhysics applyTo(ScrollPhysics ancestor) {
364+
return CustomBouncingScrollPhysics(parent: buildParent(ancestor));
365+
}
366+
367+
double frictionFactor(double overscrollFraction) =>
368+
0.52 * pow(1 - overscrollFraction, 2);
369+
370+
@override
371+
double applyPhysicsToUserOffset(ScrollMetrics position, double offset) {
372+
assert(offset != 0.0);
373+
assert(position.minScrollExtent <= position.maxScrollExtent);
374+
if (!position.outOfRange) return offset;
375+
376+
/// -2 是因为有时候会只到 iosRefreshHeight - 1
377+
/// 会导致触发重新又从0开始的问题
378+
if (position.pixels.abs() >= (iosRefreshHeight - 2)) {
379+
return 0;
380+
}
381+
final double overscrollPastStart =
382+
max(position.minScrollExtent - position.pixels, 0.0);
383+
final double overscrollPastEnd =
384+
max(position.pixels - position.maxScrollExtent, 0.0);
385+
final double overscrollPast = max(overscrollPastStart, overscrollPastEnd);
386+
387+
final bool easing = (overscrollPastStart > 0.0 && offset < 0.0) ||
388+
(overscrollPastEnd > 0.0 && offset > 0.0);
389+
390+
final double friction = easing
391+
? frictionFactor(
392+
(overscrollPast - offset.abs()) / position.viewportDimension)
393+
: frictionFactor(overscrollPast / position.viewportDimension);
394+
395+
396+
397+
final double direction = offset.sign;
398+
399+
print("easing $easing overscrollPastStart $overscrollPastStart");
400+
401+
return direction * _applyFriction(overscrollPast, offset.abs(), friction);
402+
}
403+
404+
static double _applyFriction(
405+
double extentOutside, double absDelta, double gamma) {
406+
assert(absDelta > 0);
407+
double total = 0.0;
408+
if (extentOutside > 0) {
409+
final double deltaToLimit = extentOutside / gamma;
410+
if (absDelta < deltaToLimit) return absDelta * gamma;
411+
total += extentOutside;
412+
absDelta -= deltaToLimit;
413+
}
414+
return total + absDelta;
415+
}
416+
417+
@override
418+
double applyBoundaryConditions(ScrollMetrics position, double value) => 0.0;
419+
420+
@override
421+
Simulation createBallisticSimulation(
422+
ScrollMetrics position, double velocity) {
423+
final Tolerance tolerance = this.tolerance;
424+
if (velocity.abs() >= tolerance.velocity || position.outOfRange) {
425+
return BouncingScrollSimulation(
426+
spring: spring,
427+
position: position.pixels,
428+
velocity: velocity * 0.91,
429+
leadingExtent: position.minScrollExtent,
430+
trailingExtent: position.maxScrollExtent,
431+
tolerance: tolerance,
432+
);
433+
}
434+
return null;
435+
}
436+
437+
@override
438+
double get minFlingVelocity => 50.0 * 2.0;
439+
440+
@override
441+
double carriedMomentum(double existingVelocity) {
442+
return existingVelocity.sign *
443+
min(0.000816 * pow(existingVelocity.abs(), 1.967).toDouble(), 40000.0);
444+
}
445+
446+
@override
447+
double get dragStartDistanceMotionThreshold => 3.5;
448+
}

pubspec.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,7 @@ flutter:
102102
- static/file/rejection.json
103103
- static/file/rejection2.json
104104
- static/file/flare_flutter_2.flr
105+
- static/file/loading_world_now.flr
105106

106107
fonts:
107108
- family: wxcIconFont

static/file/loading_world_now.flr

99.8 KB
Binary file not shown.

0 commit comments

Comments
 (0)