mirror of
https://github.com/HChaZZY/PiliPlus.git
synced 2025-12-06 09:13:48 +08:00
opt: refresh indicator
Signed-off-by: bggRGjQaUbCoE <githubaccount56556@proton.me>
This commit is contained in:
@@ -12,7 +12,7 @@ Widget refreshIndicator({
|
|||||||
return RefreshIndicator(
|
return RefreshIndicator(
|
||||||
displacement: displacement,
|
displacement: displacement,
|
||||||
onRefresh: onRefresh,
|
onRefresh: onRefresh,
|
||||||
child: child,
|
child: (onCancelDrag) => child,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -188,7 +188,7 @@ class RefreshIndicator extends StatefulWidget {
|
|||||||
/// will appear when child's Scrollable descendant is over-scrolled.
|
/// will appear when child's Scrollable descendant is over-scrolled.
|
||||||
///
|
///
|
||||||
/// Typically a [ListView] or [CustomScrollView].
|
/// Typically a [ListView] or [CustomScrollView].
|
||||||
final Widget child;
|
final Widget Function(ValueChanged<double> onCancelDrag) child;
|
||||||
|
|
||||||
/// The distance from the child's top or bottom [edgeOffset] where
|
/// The distance from the child's top or bottom [edgeOffset] where
|
||||||
/// the refresh indicator will settle. During the drag that exposes the refresh
|
/// the refresh indicator will settle. During the drag that exposes the refresh
|
||||||
@@ -270,6 +270,8 @@ class RefreshIndicator extends StatefulWidget {
|
|||||||
RefreshIndicatorState createState() => RefreshIndicatorState();
|
RefreshIndicatorState createState() => RefreshIndicatorState();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool isRefreshing = false;
|
||||||
|
|
||||||
/// Contains the state for a [RefreshIndicator]. This class can be used to
|
/// Contains the state for a [RefreshIndicator]. This class can be used to
|
||||||
/// programmatically show the refresh indicator, see the [show] method.
|
/// programmatically show the refresh indicator, see the [show] method.
|
||||||
class RefreshIndicatorState extends State<RefreshIndicator>
|
class RefreshIndicatorState extends State<RefreshIndicator>
|
||||||
@@ -368,6 +370,8 @@ class RefreshIndicatorState extends State<RefreshIndicator>
|
|||||||
_start(notification.metrics.axisDirection);
|
_start(notification.metrics.axisDirection);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
double? containerExtent;
|
||||||
|
|
||||||
bool _handleScrollNotification(ScrollNotification notification) {
|
bool _handleScrollNotification(ScrollNotification notification) {
|
||||||
if (!widget.notificationPredicate(notification)) {
|
if (!widget.notificationPredicate(notification)) {
|
||||||
return false;
|
return false;
|
||||||
@@ -443,6 +447,7 @@ class RefreshIndicatorState extends State<RefreshIndicator>
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (_mode == _RefreshIndicatorMode.drag) {
|
if (_mode == _RefreshIndicatorMode.drag) {
|
||||||
|
isRefreshing = true;
|
||||||
notification.disallowIndicator();
|
notification.disallowIndicator();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -470,6 +475,7 @@ class RefreshIndicatorState extends State<RefreshIndicator>
|
|||||||
}
|
}
|
||||||
|
|
||||||
void _checkDragOffset(double containerExtent) {
|
void _checkDragOffset(double containerExtent) {
|
||||||
|
this.containerExtent ??= containerExtent;
|
||||||
assert(_mode == _RefreshIndicatorMode.drag ||
|
assert(_mode == _RefreshIndicatorMode.drag ||
|
||||||
_mode == _RefreshIndicatorMode.armed);
|
_mode == _RefreshIndicatorMode.armed);
|
||||||
double newValue =
|
double newValue =
|
||||||
@@ -487,6 +493,7 @@ class RefreshIndicatorState extends State<RefreshIndicator>
|
|||||||
|
|
||||||
// Stop showing the refresh indicator.
|
// Stop showing the refresh indicator.
|
||||||
Future<void> _dismiss(_RefreshIndicatorMode newMode) async {
|
Future<void> _dismiss(_RefreshIndicatorMode newMode) async {
|
||||||
|
isRefreshing = false;
|
||||||
await Future<void>.value();
|
await Future<void>.value();
|
||||||
// This can only be called from _show() when refreshing and
|
// This can only be called from _show() when refreshing and
|
||||||
// _handleScrollNotification in response to a ScrollEndNotification or
|
// _handleScrollNotification in response to a ScrollEndNotification or
|
||||||
@@ -579,7 +586,10 @@ class RefreshIndicatorState extends State<RefreshIndicator>
|
|||||||
onNotification: _handleScrollNotification,
|
onNotification: _handleScrollNotification,
|
||||||
child: NotificationListener<OverscrollIndicatorNotification>(
|
child: NotificationListener<OverscrollIndicatorNotification>(
|
||||||
onNotification: _handleIndicatorNotification,
|
onNotification: _handleIndicatorNotification,
|
||||||
child: widget.child,
|
child: widget.child((delta) {
|
||||||
|
_dragOffset = _dragOffset! + delta;
|
||||||
|
_checkDragOffset(containerExtent!);
|
||||||
|
}),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
assert(() {
|
assert(() {
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
import 'package:PiliPlus/common/widgets/refresh_indicator.dart';
|
||||||
import 'package:PiliPlus/utils/storage.dart';
|
import 'package:PiliPlus/utils/storage.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
@@ -52,3 +53,41 @@ class CustomTabBarViewClampingScrollPhysics extends ClampingScrollPhysics {
|
|||||||
damping: GStorage.springDescription[2],
|
damping: GStorage.springDescription[2],
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class CustomScrollPosition extends ScrollPositionWithSingleContext {
|
||||||
|
CustomScrollPosition({
|
||||||
|
required super.physics,
|
||||||
|
required super.context,
|
||||||
|
required this.onCancelDrag,
|
||||||
|
});
|
||||||
|
|
||||||
|
final ValueChanged<double> onCancelDrag;
|
||||||
|
|
||||||
|
@override
|
||||||
|
void applyUserOffset(double delta) {
|
||||||
|
if (isRefreshing && delta < 0) {
|
||||||
|
onCancelDrag(delta);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
super.applyUserOffset(delta);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class CustomScrollController extends ScrollController {
|
||||||
|
CustomScrollController(this.onCancelDrag);
|
||||||
|
|
||||||
|
final ValueChanged<double> onCancelDrag;
|
||||||
|
|
||||||
|
@override
|
||||||
|
CustomScrollPosition createScrollPosition(
|
||||||
|
ScrollPhysics physics,
|
||||||
|
ScrollContext context,
|
||||||
|
ScrollPosition? oldPosition,
|
||||||
|
) {
|
||||||
|
return CustomScrollPosition(
|
||||||
|
physics: physics.applyTo(const AlwaysScrollableScrollPhysics()),
|
||||||
|
context: context,
|
||||||
|
onCancelDrag: onCancelDrag,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,8 +1,9 @@
|
|||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
|
|
||||||
import 'package:PiliPlus/common/widgets/refresh_indicator.dart';
|
import 'package:PiliPlus/common/widgets/refresh_indicator.dart';
|
||||||
|
import 'package:PiliPlus/common/widgets/spring_physics.dart';
|
||||||
import 'package:PiliPlus/http/loading_state.dart';
|
import 'package:PiliPlus/http/loading_state.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart' hide RefreshIndicator;
|
||||||
import 'package:flutter/rendering.dart';
|
import 'package:flutter/rendering.dart';
|
||||||
import 'package:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
import 'package:PiliPlus/common/constants.dart';
|
import 'package:PiliPlus/common/constants.dart';
|
||||||
@@ -67,12 +68,12 @@ class _RcmdPageState extends State<RcmdPage>
|
|||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
borderRadius: StyleString.mdRadius,
|
borderRadius: StyleString.mdRadius,
|
||||||
),
|
),
|
||||||
child: refreshIndicator(
|
child: RefreshIndicator(
|
||||||
onRefresh: () async {
|
onRefresh: () async {
|
||||||
await _controller.onRefresh();
|
await _controller.onRefresh();
|
||||||
},
|
},
|
||||||
child: CustomScrollView(
|
child: (onCancelDrag) => CustomScrollView(
|
||||||
controller: _controller.scrollController,
|
controller: CustomScrollController(onCancelDrag),
|
||||||
physics: const AlwaysScrollableScrollPhysics(),
|
physics: const AlwaysScrollableScrollPhysics(),
|
||||||
slivers: [
|
slivers: [
|
||||||
SliverPadding(
|
SliverPadding(
|
||||||
|
|||||||
Reference in New Issue
Block a user