Signed-off-by: bggRGjQaUbCoE <githubaccount56556@proton.me>
This commit is contained in:
bggRGjQaUbCoE
2025-07-23 16:47:11 +08:00
parent 148e0872b4
commit 418a1e8d39
821 changed files with 29467 additions and 25520 deletions

View File

@@ -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: