Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Add parameter maxPullHeight Indicator、Header、Footer、ClassicFoot… #611

Closed
wants to merge 3 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 12 additions & 1 deletion example/lib/page/sample/sample_page.dart
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:get/get.dart';

import 'test_max_pull_height_page.dart';

class SamplePage extends StatefulWidget {
const SamplePage({Key? key}) : super(key: key);

Expand Down Expand Up @@ -88,7 +90,7 @@ class _SamplePageState extends State<SamplePage> {
icon: Icons.pages,
onTap: () => Get.toNamed(Routes.pageViewSample),
),
if (kDebugMode)
if (kDebugMode) ...[
ListItem(
title: 'Test',
subtitle: 'EasyRefresh test page',
Expand All @@ -97,6 +99,15 @@ class _SamplePageState extends State<SamplePage> {
Get.to(() => const TestPage());
},
),
ListItem(
title: 'TestMaxPullHeight',
subtitle: 'EasyRefresh test max pull height page',
icon: Icons.build,
onTap: () {
Get.to(() => const TestMaxPullHeightPage());
},
),
]
]),
),
],
Expand Down
59 changes: 59 additions & 0 deletions example/lib/page/sample/test_max_pull_height_page.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
import 'dart:async';

import 'package:easy_refresh/easy_refresh.dart';
import 'package:example/widget/skeleton_item.dart';
import 'package:flutter/material.dart';

class TestMaxPullHeightPage extends StatefulWidget {
const TestMaxPullHeightPage({Key? key}) : super(key: key);

@override
_TestMaxPullHeightPageState createState() => _TestMaxPullHeightPageState();
}

class _TestMaxPullHeightPageState extends State<TestMaxPullHeightPage> {
int _listCount = 10;

@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('TestMaxPullHeight'),
),
body: EasyRefresh(
header: const ClassicHeader(maxPullHeight: 80, clamping: true),
footer: const ClassicFooter(
maxPullHeight: 150, clamping: true, infiniteOffset: null),
child: CustomScrollView(
slivers: [
SliverList(
delegate: SliverChildBuilderDelegate((context, index) {
return const SkeletonItem();
}, childCount: _listCount)),
],
),
onRefresh: () async {
await Future.delayed(const Duration(seconds: 2), () {
if (mounted) {
setState(() {
_listCount = 20;
});
}
});
},
onLoad: () async {
if (_listCount >= 20) {
return;
}
await Future.delayed(const Duration(seconds: 2), () {
if (mounted) {
setState(() {
_listCount += 10;
});
}
});
},
),
);
}
}
2 changes: 2 additions & 0 deletions lib/src/indicator/footer/footer.dart
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ abstract class Footer extends Indicator {
bool notifyWhenInvisible = false,
IndicatorStateListenable? listenable,
bool triggerWhenReach = false,
double maxPullHeight = 0.0,
}) : super(
triggerOffset: triggerOffset,
clamping: clamping,
Expand All @@ -50,6 +51,7 @@ abstract class Footer extends Indicator {
notifyWhenInvisible: notifyWhenInvisible,
listenable: listenable,
triggerWhenReach: triggerWhenReach,
maxPullHeight: maxPullHeight,
);
}

Expand Down
2 changes: 2 additions & 0 deletions lib/src/indicator/header/header.dart
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ abstract class Header extends Indicator {
bool notifyWhenInvisible = false,
IndicatorStateListenable? listenable,
bool triggerWhenReach = false,
double maxPullHeight = 0.0
}) : super(
triggerOffset: triggerOffset,
clamping: clamping,
Expand All @@ -50,6 +51,7 @@ abstract class Header extends Indicator {
notifyWhenInvisible: notifyWhenInvisible,
listenable: listenable,
triggerWhenReach: triggerWhenReach,
maxPullHeight: maxPullHeight,
);
}

Expand Down
5 changes: 5 additions & 0 deletions lib/src/indicator/indicator.dart
Original file line number Diff line number Diff line change
Expand Up @@ -342,6 +342,10 @@ abstract class Indicator {
/// Trigger immediately when reaching the [triggerOffset].
final bool triggerWhenReach;

/// Limit the maximum height of the pull up or down
/// When zero, infinite pull.
final double maxPullHeight;

const Indicator({
required this.triggerOffset,
required this.clamping,
Expand All @@ -366,6 +370,7 @@ abstract class Indicator {
this.notifyWhenInvisible = false,
this.listenable,
this.triggerWhenReach = false,
this.maxPullHeight = 0.0,
}) : hitOver = hitOver ?? infiniteOffset != null,
infiniteHitOver = infiniteHitOver ?? infiniteOffset == null,
assert(infiniteOffset == null || infiniteOffset >= 0,
Expand Down
2 changes: 2 additions & 0 deletions lib/src/notifier/indicator_notifier.dart
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,8 @@ abstract class IndicatorNotifier extends ChangeNotifier {

double get secondaryVelocity => _indicator.secondaryVelocity;

double get maxPullHeight => _indicator.maxPullHeight;

/// Spring description.
SpringDescription? get _spring {
if (_axis == Axis.horizontal) {
Expand Down
16 changes: 15 additions & 1 deletion lib/src/physics/scroll_physics.dart
Original file line number Diff line number Diff line change
Expand Up @@ -169,12 +169,21 @@ class _ERScrollPhysics extends BouncingScrollPhysics {
}
}

// check maxPullHeight
if ((headerNotifier.outOfRange &&
headerNotifier.maxPullHeight > 0 &&
overscrollPast >= headerNotifier.maxPullHeight) ||
(footerNotifier.outOfRange &&
footerNotifier.maxPullHeight > 0 &&
overscrollPast >= footerNotifier.maxPullHeight)) {
return 0.0;
}

final double friction = easing
// Apply less resistance when easing the overscroll vs tensioning.
? frictionFactor((overscrollPast - offset.abs()) / viewportDimension)
: frictionFactor(overscrollPast / viewportDimension);
final double direction = offset.sign;

return direction * _applyFriction(overscrollPast, offset.abs(), friction);
}

Expand Down Expand Up @@ -459,6 +468,11 @@ class _ERScrollPhysics extends BouncingScrollPhysics {
}
}
}
// check maxPullHeight
if (((headerNotifier.maxPullHeight > 0 && headerNotifier.outOfRange) ||
footerNotifier.maxPullHeight > 0 && footerNotifier.outOfRange)) {
mVelocity = 0;
}
simulation = BouncingScrollSimulation(
spring: spring,
position: position.pixels,
Expand Down
2 changes: 2 additions & 0 deletions lib/src/styles/classic/footer/classic_footer.dart
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,7 @@ class ClassicFooter extends Footer {
bool? infiniteHitOver,
bool hapticFeedback = false,
bool triggerWhenReach = false,
double maxPullHeight = 0.0,
this.mainAxisAlignment = MainAxisAlignment.start,
this.backgroundColor,
this.dragText,
Expand Down Expand Up @@ -148,6 +149,7 @@ class ClassicFooter extends Footer {
position: position,
hapticFeedback: hapticFeedback,
triggerWhenReach: triggerWhenReach,
maxPullHeight: maxPullHeight,
);

@override
Expand Down
2 changes: 2 additions & 0 deletions lib/src/styles/classic/header/classic_header.dart
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,7 @@ class ClassicHeader extends Header {
bool? infiniteHitOver,
bool hapticFeedback = false,
bool triggerWhenReach = false,
double maxPullHeight = 0.0,
this.mainAxisAlignment = MainAxisAlignment.center,
this.backgroundColor,
this.dragText,
Expand Down Expand Up @@ -148,6 +149,7 @@ class ClassicHeader extends Header {
position: position,
hapticFeedback: hapticFeedback,
triggerWhenReach: triggerWhenReach,
maxPullHeight: maxPullHeight,
);

@override
Expand Down