Skip to content

Commit

Permalink
feat: Add CupertinoIndicator.
Browse files Browse the repository at this point in the history
  • Loading branch information
xuelongqy committed Jul 10, 2022
1 parent 304cf80 commit 3275789
Show file tree
Hide file tree
Showing 19 changed files with 296 additions and 12 deletions.
3 changes: 2 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
# Change log

## Next
> fix: use notifyListeners after ChangeNotifier disposed. Thanks laiiihz for [PR#555](https://github.com/xuelongqy/flutter_easy_refresh/pull/555).
> fix: Use notifyListeners after ChangeNotifier disposed. Thanks laiiihz for [PR#555](https://github.com/xuelongqy/flutter_easy_refresh/pull/555).
> feat: ClassicHeader、ClassicFooter add IconThemeData. Thanks Lay523 for [PR#562](https://github.com/xuelongqy/flutter_easy_refresh/pull/562).
> feat: ClassicIndicator add [progressIndicatorSize] and [progressIndicatorStrokeWidth].
> feat: Add CupertinoIndicator.
## V 3.0.0+3
> fix: dart >=2.13.0.
Expand Down
89 changes: 89 additions & 0 deletions example/lib/page/style/cupertino_page.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
import 'package:easy_refresh/easy_refresh.dart';
import 'package:example/widget/skeleton_item.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';

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

@override
State<CupertinoIndicatorPage> createState() => _CupertinoIndicatorPageState();
}

class _CupertinoIndicatorPageState extends State<CupertinoIndicatorPage> {
int _count = 10;
late EasyRefreshController _controller;

@override
void initState() {
super.initState();
_controller = EasyRefreshController(
controlFinishRefresh: true,
controlFinishLoad: true,
);
}

@override
void dispose() {
_controller.dispose();
super.dispose();
}

@override
Widget build(BuildContext context) {
return Material(
child: CupertinoPageScaffold(
child: EasyRefresh(
controller: _controller,
header: const CupertinoHeader(
position: IndicatorPosition.locator,
safeArea: false,
),
footer: const CupertinoFooter(
position: IndicatorPosition.locator,
),
onRefresh: () async {
await Future.delayed(const Duration(seconds: 2));
if (!mounted) {
return;
}
setState(() {
_count = 10;
});
_controller.finishRefresh();
_controller.resetFooter();
},
onLoad: () async {
await Future.delayed(const Duration(seconds: 2));
if (!mounted) {
return;
}
setState(() {
_count += 5;
});
_controller.finishLoad(_count >= 20
? IndicatorResult.noMore
: IndicatorResult.success);
},
child: CustomScrollView(
slivers: [
const CupertinoSliverNavigationBar(
largeTitle: Text('iOS Cupertino'),
),
const HeaderLocator.sliver(),
SliverList(
delegate: SliverChildBuilderDelegate(
(context, index) {
return const SkeletonItem();
},
childCount: _count,
),
),
const FooterLocator.sliver(),
],
),
),
),
);
}
}
7 changes: 7 additions & 0 deletions example/lib/page/style/style_page.dart
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import 'package:example/page/style/bezier_circle_page.dart';
import 'package:example/page/style/bezier_page.dart';
import 'package:example/page/style/classical_page.dart';
import 'package:example/page/style/cupertino_page.dart';
import 'package:example/page/style/delivery_page.dart';
import 'package:example/page/style/halloween_page.dart';
import 'package:example/page/style/material_page.dart';
Expand Down Expand Up @@ -52,6 +53,12 @@ class _StylePageState extends State<StylePage> {
icon: Icons.refresh,
onTap: () => Get.to(() => const MaterialIndicatorPage()),
),
ListItem(
title: 'Cupertino',
subtitle: 'iOS Cupertino',
icon: Icons.apple,
onTap: () => Get.to(() => const CupertinoIndicatorPage()),
),
ListItem(
title: 'Bezier',
subtitle: 'Bezier curve'.tr,
Expand Down
2 changes: 2 additions & 0 deletions example/pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ dependencies:
flutter_localizations:
sdk: flutter

cupertino_icons: ^1.0.5

url_launcher: ^6.1.4
flutter_spinkit: ^5.1.0
flare_flutter: ^3.0.2
Expand Down
4 changes: 4 additions & 0 deletions lib/easy_refresh.dart
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ library easy_refresh;
import 'dart:math' as math;
import 'dart:async';

import 'package:flutter/cupertino.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart';
Expand Down Expand Up @@ -43,3 +44,6 @@ part 'src/styles/taurus/footer/taurus_footer.dart';
part 'src/styles/delivery/delivery_indicator.dart';
part 'src/styles/delivery/header/delivery_header.dart';
part 'src/styles/delivery/footer/delivery_footer.dart';
part 'src/styles/cupertino/cupertino_indicator.dart';
part 'src/styles/cupertino/header/cupertino_header.dart';
part 'src/styles/cupertino/footer/cupertino_footer.dart';
2 changes: 1 addition & 1 deletion lib/src/styles/bezier/footer/bezier_footer.dart
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ class BezierFooter extends Footer {
/// Background color.
final Color? backgroundColor;

BezierFooter({
const BezierFooter({
this.key,
double triggerOffset = 100,
bool clamping = false,
Expand Down
2 changes: 1 addition & 1 deletion lib/src/styles/bezier/header/bezier_circle_header.dart
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ class BezierCircleHeader extends Header {
/// Background color.
final Color? backgroundColor;

BezierCircleHeader({
const BezierCircleHeader({
this.key,
double triggerOffset = 100,
bool clamping = false,
Expand Down
2 changes: 1 addition & 1 deletion lib/src/styles/bezier/header/bezier_header.dart
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ class BezierHeader extends Header {
/// Background color.
final Color? backgroundColor;

BezierHeader({
const BezierHeader({
this.key,
double triggerOffset = 100,
bool clamping = false,
Expand Down
87 changes: 87 additions & 0 deletions lib/src/styles/cupertino/cupertino_indicator.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
part of easy_refresh;

const double _kDefaultCupertinoIndicatorRadius = 14.0;

/// Cupertino indicator.
/// Base widget for [CupertinoHeader] and [CupertinoFooter].
class _CupertinoIndicator extends StatefulWidget {
/// Indicator properties and state.
final IndicatorState state;

/// True for up and left.
/// False for down and right.
final bool reverse;

const _CupertinoIndicator({
Key? key,
required this.state,
required this.reverse,
}) : super(key: key);

@override
State<_CupertinoIndicator> createState() => _CupertinoIndicatorState();
}

class _CupertinoIndicatorState extends State<_CupertinoIndicator> {
IndicatorMode get _mode => widget.state.mode;
double get _offset => widget.state.offset;
double get _actualTriggerOffset => widget.state.actualTriggerOffset;

double get _radius => _kDefaultCupertinoIndicatorRadius;

Widget _buildIndicator() {
final scale = (_offset / _actualTriggerOffset).clamp(0.0, 1.0);
switch (_mode) {
case IndicatorMode.drag:
case IndicatorMode.armed:
const Curve opacityCurve = Interval(
0.0,
0.8,
curve: Curves.easeInOut,
);
return Opacity(
opacity: opacityCurve.transform(scale),
child: CupertinoActivityIndicator.partiallyRevealed(
radius: _radius,
progress: math.min(scale, 0.99),
),
);
case IndicatorMode.ready:
case IndicatorMode.processing:
case IndicatorMode.processed:
return CupertinoActivityIndicator(
radius: _radius,
);
case IndicatorMode.done:
return CupertinoActivityIndicator(
radius: _radius * scale,
);
default:
return Container();
}
}

@override
Widget build(BuildContext context) {
return Stack(
alignment: Alignment.center,
children: [
SizedBox(
height: _offset,
width: double.infinity,
),
Positioned(
top: 0,
left: 0,
right: 0,
child: Container(
alignment: Alignment.center,
height: _actualTriggerOffset,
width: double.infinity,
child: _buildIndicator(),
),
),
],
);
}
}
47 changes: 47 additions & 0 deletions lib/src/styles/cupertino/footer/cupertino_footer.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
part of easy_refresh;

class CupertinoFooter extends Footer {
final Key? key;

const CupertinoFooter({
this.key,
double triggerOffset = 60,
bool clamping = false,
IndicatorPosition position = IndicatorPosition.behind,
Duration processedDuration = Duration.zero,
SpringDescription? spring,
SpringBuilder? readySpringBuilder,
bool springRebound = true,
FrictionFactor? frictionFactor,
bool safeArea = true,
double? infiniteOffset = 60,
bool? hitOver,
bool? infiniteHitOver,
bool hapticFeedback = false,
}) : super(
triggerOffset: triggerOffset,
clamping: clamping,
processedDuration: processedDuration,
spring: spring,
readySpringBuilder: readySpringBuilder,
springRebound: springRebound,
frictionFactor: frictionFactor,
safeArea: safeArea,
infiniteOffset: infiniteOffset,
hitOver: hitOver,
infiniteHitOver: infiniteHitOver,
position: position,
hapticFeedback: hapticFeedback,
);

@override
Widget build(BuildContext context, IndicatorState state) {
assert(state.axis == Axis.vertical,
'CupertinoFooter does not support horizontal scrolling.');
return _CupertinoIndicator(
key: key,
state: state,
reverse: state.reverse,
);
}
}
47 changes: 47 additions & 0 deletions lib/src/styles/cupertino/header/cupertino_header.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
part of easy_refresh;

class CupertinoHeader extends Header {
final Key? key;

const CupertinoHeader({
this.key,
double triggerOffset = 60,
bool clamping = false,
IndicatorPosition position = IndicatorPosition.behind,
Duration processedDuration = const Duration(seconds: 1),
SpringDescription? spring,
SpringBuilder? readySpringBuilder,
bool springRebound = false,
FrictionFactor? frictionFactor,
bool safeArea = true,
double? infiniteOffset,
bool? hitOver,
bool? infiniteHitOver,
bool hapticFeedback = false,
}) : super(
triggerOffset: triggerOffset,
clamping: clamping,
processedDuration: processedDuration,
spring: spring,
readySpringBuilder: readySpringBuilder,
springRebound: springRebound,
frictionFactor: frictionFactor,
safeArea: safeArea,
infiniteOffset: infiniteOffset,
hitOver: hitOver,
infiniteHitOver: infiniteHitOver,
position: position,
hapticFeedback: hapticFeedback,
);

@override
Widget build(BuildContext context, IndicatorState state) {
assert(state.axis == Axis.vertical,
'CupertinoHeader does not support horizontal scrolling.');
return _CupertinoIndicator(
key: key,
state: state,
reverse: state.reverse,
);
}
}
2 changes: 1 addition & 1 deletion lib/src/styles/delivery/footer/delivery_footer.dart
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ class DeliveryFooter extends Footer {
/// Sky color.
final Color? skyColor;

DeliveryFooter({
const DeliveryFooter({
this.key,
double triggerOffset = kDeliveryTriggerOffset,
bool clamping = false,
Expand Down
2 changes: 1 addition & 1 deletion lib/src/styles/delivery/header/delivery_header.dart
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ class DeliveryHeader extends Header {
/// Sky color.
final Color? skyColor;

DeliveryHeader({
const DeliveryHeader({
this.key,
double triggerOffset = kDeliveryTriggerOffset,
bool clamping = false,
Expand Down
2 changes: 1 addition & 1 deletion lib/src/styles/material/footer/material_footer.dart
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ class MaterialFooter extends Footer {
/// See [BezierBackground.bounce].
final bool bezierBackgroundBounce;

MaterialFooter({
const MaterialFooter({
this.key,
double triggerOffset = 100,
bool clamping = true,
Expand Down
2 changes: 1 addition & 1 deletion lib/src/styles/material/header/material_header.dart
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ class MaterialHeader extends Header {
/// See [BezierBackground.bounce].
final bool bezierBackgroundBounce;

MaterialHeader({
const MaterialHeader({
this.key,
double triggerOffset = 100,
bool clamping = true,
Expand Down
Loading

0 comments on commit 3275789

Please sign in to comment.