mirror of
https://github.com/HChaZZY/PiliPlus.git
synced 2025-12-20 00:56:31 +08:00
@@ -167,9 +167,9 @@ class RefreshIndicator extends StatefulWidget {
|
||||
this.strokeWidth = RefreshProgressIndicator.defaultStrokeWidth,
|
||||
this.triggerMode = RefreshIndicatorTriggerMode.onEdge,
|
||||
this.elevation = 2.0,
|
||||
}) : _indicatorType = _IndicatorType.material,
|
||||
onStatusChange = null,
|
||||
assert(elevation >= 0.0);
|
||||
}) : _indicatorType = _IndicatorType.material,
|
||||
onStatusChange = null,
|
||||
assert(elevation >= 0.0);
|
||||
|
||||
/// Creates an adaptive [RefreshIndicator] based on whether the target
|
||||
/// platform is iOS or macOS, following Material design's
|
||||
@@ -201,9 +201,9 @@ class RefreshIndicator extends StatefulWidget {
|
||||
this.strokeWidth = RefreshProgressIndicator.defaultStrokeWidth,
|
||||
this.triggerMode = RefreshIndicatorTriggerMode.onEdge,
|
||||
this.elevation = 2.0,
|
||||
}) : _indicatorType = _IndicatorType.adaptive,
|
||||
onStatusChange = null,
|
||||
assert(elevation >= 0.0);
|
||||
}) : _indicatorType = _IndicatorType.adaptive,
|
||||
onStatusChange = null,
|
||||
assert(elevation >= 0.0);
|
||||
|
||||
/// Creates a [RefreshIndicator] with no spinner and calls `onRefresh` when
|
||||
/// successfully armed by a drag event.
|
||||
@@ -219,16 +219,16 @@ class RefreshIndicator extends StatefulWidget {
|
||||
this.semanticsValue,
|
||||
this.triggerMode = RefreshIndicatorTriggerMode.onEdge,
|
||||
this.elevation = 2.0,
|
||||
}) : _indicatorType = _IndicatorType.noSpinner,
|
||||
// The following parameters aren't used because [_IndicatorType.noSpinner] is being used,
|
||||
// which involves showing no spinner, hence the following parameters are useless since
|
||||
// their only use is to change the spinner's appearance.
|
||||
displacement = 0.0,
|
||||
edgeOffset = 0.0,
|
||||
color = null,
|
||||
backgroundColor = null,
|
||||
strokeWidth = 0.0,
|
||||
assert(elevation >= 0.0);
|
||||
}) : _indicatorType = _IndicatorType.noSpinner,
|
||||
// The following parameters aren't used because [_IndicatorType.noSpinner] is being used,
|
||||
// which involves showing no spinner, hence the following parameters are useless since
|
||||
// their only use is to change the spinner's appearance.
|
||||
displacement = 0.0,
|
||||
edgeOffset = 0.0,
|
||||
color = null,
|
||||
backgroundColor = null,
|
||||
strokeWidth = 0.0,
|
||||
assert(elevation >= 0.0);
|
||||
|
||||
/// The widget below this widget in the tree.
|
||||
///
|
||||
@@ -345,16 +345,20 @@ class RefreshIndicatorState extends State<RefreshIndicator>
|
||||
late Color _effectiveValueColor =
|
||||
widget.color ?? Theme.of(context).colorScheme.primary;
|
||||
|
||||
static final Animatable<double> _threeQuarterTween =
|
||||
Tween<double>(begin: 0.0, end: 0.75);
|
||||
static final Animatable<double> _threeQuarterTween = Tween<double>(
|
||||
begin: 0.0,
|
||||
end: 0.75,
|
||||
);
|
||||
|
||||
static final Animatable<double> _kDragSizeFactorLimitTween = Tween<double>(
|
||||
begin: 0.0,
|
||||
end: _kDragSizeFactorLimit,
|
||||
);
|
||||
|
||||
static final Animatable<double> _oneToZeroTween =
|
||||
Tween<double>(begin: 1.0, end: 0.0);
|
||||
static final Animatable<double> _oneToZeroTween = Tween<double>(
|
||||
begin: 1.0,
|
||||
end: 0.0,
|
||||
);
|
||||
|
||||
@protected
|
||||
@override
|
||||
@@ -408,8 +412,9 @@ class RefreshIndicatorState extends State<RefreshIndicator>
|
||||
ColorTween(
|
||||
begin: color.withAlpha(0),
|
||||
end: color.withAlpha(color.alpha),
|
||||
).chain(CurveTween(
|
||||
curve: const Interval(0.0, 1.0 / _kDragSizeFactorLimit))),
|
||||
).chain(
|
||||
CurveTween(curve: const Interval(0.0, 1.0 / _kDragSizeFactorLimit)),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -444,9 +449,9 @@ class RefreshIndicatorState extends State<RefreshIndicator>
|
||||
}
|
||||
final bool? indicatorAtTopNow =
|
||||
switch (notification.metrics.axisDirection) {
|
||||
AxisDirection.down || AxisDirection.up => true,
|
||||
AxisDirection.left || AxisDirection.right => null,
|
||||
};
|
||||
AxisDirection.down || AxisDirection.up => true,
|
||||
AxisDirection.left || AxisDirection.right => null,
|
||||
};
|
||||
if (indicatorAtTopNow != _isIndicatorAtTop) {
|
||||
if (_status == RefreshIndicatorStatus.drag ||
|
||||
_status == RefreshIndicatorStatus.armed) {
|
||||
@@ -502,7 +507,8 @@ class RefreshIndicatorState extends State<RefreshIndicator>
|
||||
}
|
||||
|
||||
bool _handleIndicatorNotification(
|
||||
OverscrollIndicatorNotification notification) {
|
||||
OverscrollIndicatorNotification notification,
|
||||
) {
|
||||
if (notification.depth != 0 || !notification.leading) {
|
||||
return false;
|
||||
}
|
||||
@@ -534,15 +540,20 @@ class RefreshIndicatorState extends State<RefreshIndicator>
|
||||
}
|
||||
|
||||
void _checkDragOffset(double containerExtent) {
|
||||
assert(_status == RefreshIndicatorStatus.drag ||
|
||||
_status == RefreshIndicatorStatus.armed);
|
||||
assert(
|
||||
_status == RefreshIndicatorStatus.drag ||
|
||||
_status == RefreshIndicatorStatus.armed,
|
||||
);
|
||||
double newValue =
|
||||
_dragOffset! / (containerExtent * kDragContainerExtentPercentage);
|
||||
if (_status == RefreshIndicatorStatus.armed) {
|
||||
newValue = math.max(newValue, 1.0 / _kDragSizeFactorLimit);
|
||||
}
|
||||
_positionController.value =
|
||||
clampDouble(newValue, 0.0, 1.0); // This triggers various rebuilds.
|
||||
_positionController.value = clampDouble(
|
||||
newValue,
|
||||
0.0,
|
||||
1.0,
|
||||
); // This triggers various rebuilds.
|
||||
if (_status == RefreshIndicatorStatus.drag &&
|
||||
_valueColor.value!.alpha == _effectiveValueColor.alpha) {
|
||||
_status = RefreshIndicatorStatus.armed;
|
||||
@@ -556,19 +567,25 @@ class RefreshIndicatorState extends State<RefreshIndicator>
|
||||
// This can only be called from _show() when refreshing and
|
||||
// _handleScrollNotification in response to a ScrollEndNotification or
|
||||
// direction change.
|
||||
assert(newMode == RefreshIndicatorStatus.canceled ||
|
||||
newMode == RefreshIndicatorStatus.done);
|
||||
assert(
|
||||
newMode == RefreshIndicatorStatus.canceled ||
|
||||
newMode == RefreshIndicatorStatus.done,
|
||||
);
|
||||
setState(() {
|
||||
_status = newMode;
|
||||
widget.onStatusChange?.call(_status);
|
||||
});
|
||||
switch (_status!) {
|
||||
case RefreshIndicatorStatus.done:
|
||||
await _scaleController.animateTo(1.0,
|
||||
duration: _kIndicatorScaleDuration);
|
||||
await _scaleController.animateTo(
|
||||
1.0,
|
||||
duration: _kIndicatorScaleDuration,
|
||||
);
|
||||
case RefreshIndicatorStatus.canceled:
|
||||
await _positionController.animateTo(0.0,
|
||||
duration: _kIndicatorScaleDuration);
|
||||
await _positionController.animateTo(
|
||||
0.0,
|
||||
duration: _kIndicatorScaleDuration,
|
||||
);
|
||||
case RefreshIndicatorStatus.armed:
|
||||
case RefreshIndicatorStatus.drag:
|
||||
case RefreshIndicatorStatus.refresh:
|
||||
@@ -592,23 +609,25 @@ class RefreshIndicatorState extends State<RefreshIndicator>
|
||||
_status = RefreshIndicatorStatus.snap;
|
||||
widget.onStatusChange?.call(_status);
|
||||
_positionController
|
||||
.animateTo(1.0 / _kDragSizeFactorLimit,
|
||||
duration: _kIndicatorSnapDuration)
|
||||
.animateTo(
|
||||
1.0 / _kDragSizeFactorLimit,
|
||||
duration: _kIndicatorSnapDuration,
|
||||
)
|
||||
.whenComplete(() {
|
||||
if (mounted && _status == RefreshIndicatorStatus.snap) {
|
||||
setState(() {
|
||||
// Show the indeterminate progress indicator.
|
||||
_status = RefreshIndicatorStatus.refresh;
|
||||
});
|
||||
if (mounted && _status == RefreshIndicatorStatus.snap) {
|
||||
setState(() {
|
||||
// Show the indeterminate progress indicator.
|
||||
_status = RefreshIndicatorStatus.refresh;
|
||||
});
|
||||
|
||||
widget.onRefresh().whenComplete(() {
|
||||
if (mounted && _status == RefreshIndicatorStatus.refresh) {
|
||||
completer.complete();
|
||||
_dismiss(RefreshIndicatorStatus.done);
|
||||
widget.onRefresh().whenComplete(() {
|
||||
if (mounted && _status == RefreshIndicatorStatus.refresh) {
|
||||
completer.complete();
|
||||
_dismiss(RefreshIndicatorStatus.done);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/// Show the refresh indicator and run the refresh callback as if it had
|
||||
@@ -662,7 +681,7 @@ class RefreshIndicatorState extends State<RefreshIndicator>
|
||||
|
||||
final bool showIndeterminateIndicator =
|
||||
_status == RefreshIndicatorStatus.refresh ||
|
||||
_status == RefreshIndicatorStatus.done;
|
||||
_status == RefreshIndicatorStatus.done;
|
||||
|
||||
return Stack(
|
||||
clipBehavior: Clip.none,
|
||||
@@ -692,22 +711,25 @@ class RefreshIndicatorState extends State<RefreshIndicator>
|
||||
builder: (BuildContext context, Widget? child) {
|
||||
final Widget materialIndicator =
|
||||
RefreshProgressIndicator(
|
||||
semanticsLabel: widget.semanticsLabel ??
|
||||
MaterialLocalizations.of(context)
|
||||
.refreshIndicatorSemanticLabel,
|
||||
semanticsValue: widget.semanticsValue,
|
||||
value:
|
||||
showIndeterminateIndicator ? null : _value.value,
|
||||
valueColor: _valueColor,
|
||||
backgroundColor: widget.backgroundColor,
|
||||
strokeWidth: widget.strokeWidth,
|
||||
elevation: widget.elevation,
|
||||
);
|
||||
semanticsLabel:
|
||||
widget.semanticsLabel ??
|
||||
MaterialLocalizations.of(
|
||||
context,
|
||||
).refreshIndicatorSemanticLabel,
|
||||
semanticsValue: widget.semanticsValue,
|
||||
value: showIndeterminateIndicator
|
||||
? null
|
||||
: _value.value,
|
||||
valueColor: _valueColor,
|
||||
backgroundColor: widget.backgroundColor,
|
||||
strokeWidth: widget.strokeWidth,
|
||||
elevation: widget.elevation,
|
||||
);
|
||||
|
||||
final Widget cupertinoIndicator =
|
||||
CupertinoActivityIndicator(
|
||||
color: widget.color,
|
||||
);
|
||||
color: widget.color,
|
||||
);
|
||||
|
||||
switch (widget._indicatorType) {
|
||||
case _IndicatorType.material:
|
||||
|
||||
Reference in New Issue
Block a user