mirror of
https://github.com/bggRGjQaUbCoE/PiliPlus.git
synced 2026-05-30 23:58:13 +08:00
@@ -8,7 +8,7 @@ import 'dart:io' show Platform;
|
|||||||
import 'package:PiliPlus/common/widgets/scroll_behavior.dart';
|
import 'package:PiliPlus/common/widgets/scroll_behavior.dart';
|
||||||
import 'package:PiliPlus/utils/storage_pref.dart';
|
import 'package:PiliPlus/utils/storage_pref.dart';
|
||||||
import 'package:flutter/foundation.dart' show clampDouble;
|
import 'package:flutter/foundation.dart' show clampDouble;
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart' hide RefreshIndicator;
|
||||||
|
|
||||||
double displacement = Pref.refreshDisplacement;
|
double displacement = Pref.refreshDisplacement;
|
||||||
|
|
||||||
@@ -207,9 +207,11 @@ class RefreshIndicator extends StatefulWidget {
|
|||||||
/// 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>
|
||||||
with SingleTickerProviderStateMixin<RefreshIndicator> {
|
with TickerProviderStateMixin<RefreshIndicator> {
|
||||||
late AnimationController _positionController;
|
late AnimationController _positionController;
|
||||||
|
late AnimationController _scaleController;
|
||||||
late Animation<double> _positionFactor;
|
late Animation<double> _positionFactor;
|
||||||
|
late Animation<double> _scaleFactor;
|
||||||
late Animation<double> _value;
|
late Animation<double> _value;
|
||||||
late Animation<Color?> _valueColor;
|
late Animation<Color?> _valueColor;
|
||||||
|
|
||||||
@@ -229,6 +231,11 @@ class RefreshIndicatorState extends State<RefreshIndicator>
|
|||||||
end: _kDragSizeFactorLimit,
|
end: _kDragSizeFactorLimit,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
static final Animatable<double> _oneToZeroTween = Tween<double>(
|
||||||
|
begin: 1.0,
|
||||||
|
end: 0.0,
|
||||||
|
);
|
||||||
|
|
||||||
@protected
|
@protected
|
||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
@@ -238,6 +245,9 @@ class RefreshIndicatorState extends State<RefreshIndicator>
|
|||||||
|
|
||||||
// The "value" of the circular progress indicator during a drag.
|
// The "value" of the circular progress indicator during a drag.
|
||||||
_value = _positionController.drive(_threeQuarterTween);
|
_value = _positionController.drive(_threeQuarterTween);
|
||||||
|
|
||||||
|
_scaleController = AnimationController(vsync: this);
|
||||||
|
_scaleFactor = _scaleController.drive(_oneToZeroTween);
|
||||||
}
|
}
|
||||||
|
|
||||||
@protected
|
@protected
|
||||||
@@ -260,6 +270,7 @@ class RefreshIndicatorState extends State<RefreshIndicator>
|
|||||||
@override
|
@override
|
||||||
void dispose() {
|
void dispose() {
|
||||||
_positionController.dispose();
|
_positionController.dispose();
|
||||||
|
_scaleController.dispose();
|
||||||
super.dispose();
|
super.dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -295,14 +306,11 @@ class RefreshIndicatorState extends State<RefreshIndicator>
|
|||||||
_start();
|
_start();
|
||||||
}
|
}
|
||||||
|
|
||||||
double? _viewportDimension;
|
|
||||||
|
|
||||||
bool _handleScrollNotification(ScrollNotification notification) {
|
bool _handleScrollNotification(ScrollNotification notification) {
|
||||||
if (!widget.notificationPredicate(notification)) {
|
if (!widget.notificationPredicate(notification)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (_shouldStart(notification)) {
|
if (_shouldStart(notification)) {
|
||||||
_viewportDimension = notification.metrics.viewportDimension;
|
|
||||||
setState(() {
|
setState(() {
|
||||||
_status = RefreshIndicatorStatus.drag;
|
_status = RefreshIndicatorStatus.drag;
|
||||||
});
|
});
|
||||||
@@ -363,6 +371,7 @@ class RefreshIndicatorState extends State<RefreshIndicator>
|
|||||||
assert(_status == null);
|
assert(_status == null);
|
||||||
assert(_dragOffset == null);
|
assert(_dragOffset == null);
|
||||||
_dragOffset = 0.0;
|
_dragOffset = 0.0;
|
||||||
|
_scaleController.value = 0.0;
|
||||||
_positionController.value = 0.0;
|
_positionController.value = 0.0;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -395,7 +404,10 @@ class RefreshIndicatorState extends State<RefreshIndicator>
|
|||||||
});
|
});
|
||||||
switch (_status!) {
|
switch (_status!) {
|
||||||
case RefreshIndicatorStatus.done:
|
case RefreshIndicatorStatus.done:
|
||||||
break;
|
await _scaleController.animateTo(
|
||||||
|
1.0,
|
||||||
|
duration: _kIndicatorScaleDuration,
|
||||||
|
);
|
||||||
case RefreshIndicatorStatus.canceled:
|
case RefreshIndicatorStatus.canceled:
|
||||||
await _positionController.animateTo(
|
await _positionController.animateTo(
|
||||||
0.0,
|
0.0,
|
||||||
@@ -509,6 +521,8 @@ class RefreshIndicatorState extends State<RefreshIndicator>
|
|||||||
padding: EdgeInsets.only(top: widget.displacement),
|
padding: EdgeInsets.only(top: widget.displacement),
|
||||||
child: Align(
|
child: Align(
|
||||||
alignment: Alignment.topCenter,
|
alignment: Alignment.topCenter,
|
||||||
|
child: ScaleTransition(
|
||||||
|
scale: _scaleFactor,
|
||||||
child: AnimatedBuilder(
|
child: AnimatedBuilder(
|
||||||
animation: _positionController,
|
animation: _positionController,
|
||||||
builder: (context, child) => RefreshProgressIndicator(
|
builder: (context, child) => RefreshProgressIndicator(
|
||||||
@@ -523,6 +537,7 @@ class RefreshIndicatorState extends State<RefreshIndicator>
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
),
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
if (!widget.isClampingScrollPhysics &&
|
if (!widget.isClampingScrollPhysics &&
|
||||||
@@ -538,12 +553,11 @@ class RefreshIndicatorState extends State<RefreshIndicator>
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool _onDrag(double offset) {
|
bool _onDrag(double offset, double viewportDimension) {
|
||||||
if (_positionController.value > 0.0 &&
|
if (_positionController.value > 0.0 &&
|
||||||
_status == RefreshIndicatorStatus.drag &&
|
_status == RefreshIndicatorStatus.drag) {
|
||||||
_viewportDimension != null) {
|
|
||||||
_dragOffset = _dragOffset! + offset;
|
_dragOffset = _dragOffset! + offset;
|
||||||
_checkDragOffset(_viewportDimension!);
|
_checkDragOffset(viewportDimension);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
@@ -577,7 +591,7 @@ class RefreshScrollBehavior extends CustomScrollBehavior {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef OnDrag = bool Function(double offset);
|
typedef OnDrag = bool Function(double offset, double viewportDimension);
|
||||||
|
|
||||||
class RefreshScrollPhysics extends ClampingScrollPhysics {
|
class RefreshScrollPhysics extends ClampingScrollPhysics {
|
||||||
const RefreshScrollPhysics({
|
const RefreshScrollPhysics({
|
||||||
@@ -597,7 +611,7 @@ class RefreshScrollPhysics extends ClampingScrollPhysics {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
double applyPhysicsToUserOffset(ScrollMetrics position, double offset) {
|
double applyPhysicsToUserOffset(ScrollMetrics position, double offset) {
|
||||||
if (offset < 0.0 && onDrag(offset)) {
|
if (offset < 0.0 && onDrag(offset, position.viewportDimension)) {
|
||||||
return 0.0;
|
return 0.0;
|
||||||
}
|
}
|
||||||
return parent?.applyPhysicsToUserOffset(position, offset) ?? offset;
|
return parent?.applyPhysicsToUserOffset(position, offset) ?? offset;
|
||||||
|
|||||||
Reference in New Issue
Block a user