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

@@ -104,16 +104,19 @@ class DraggableScrollableController extends ChangeNotifier {
/// When calling [animateTo] in widget tests, `await`ing the returned
/// [Future] may cause the test to hang and timeout. Instead, use
/// [WidgetTester.pumpAndSettle].
Future<void> animateTo(double size,
{required Duration duration, required Curve curve}) async {
Future<void> animateTo(
double size, {
required Duration duration,
required Curve curve,
}) async {
_assertAttached();
assert(size >= 0 && size <= 1);
assert(duration != Duration.zero);
final AnimationController animationController =
AnimationController.unbounded(
vsync: _attachedController!.position.context.vsync,
value: _attachedController!.extent.currentSize,
);
vsync: _attachedController!.position.context.vsync,
value: _attachedController!.extent.currentSize,
);
_animationControllers.add(animationController);
_attachedController!.position.goIdle();
// This disables any snapping until the next user interaction with the sheet.
@@ -134,8 +137,11 @@ class DraggableScrollableController extends ChangeNotifier {
);
});
await animationController.animateTo(
clampDouble(size, _attachedController!.extent.minSize,
_attachedController!.extent.maxSize),
clampDouble(
size,
_attachedController!.extent.minSize,
_attachedController!.extent.maxSize,
),
duration: duration,
curve: curve,
);
@@ -291,12 +297,13 @@ class DraggableScrollableSheet extends StatefulWidget {
this.controller,
this.shouldCloseOnMinExtent = true,
required this.builder,
}) : assert(minChildSize >= 0.0),
assert(maxChildSize <= 1.0),
assert(minChildSize <= initialChildSize),
assert(initialChildSize <= maxChildSize),
assert(snapAnimationDuration == null ||
snapAnimationDuration > Duration.zero);
}) : assert(minChildSize >= 0.0),
assert(maxChildSize <= 1.0),
assert(minChildSize <= initialChildSize),
assert(initialChildSize <= maxChildSize),
assert(
snapAnimationDuration == null || snapAnimationDuration > Duration.zero,
);
/// The initial fractional value of the parent container's height to use when
/// displaying the widget.
@@ -414,14 +421,14 @@ class _DraggableSheetExtent {
bool? hasDragged,
bool? hasChanged,
this.shouldCloseOnMinExtent = true,
}) : assert(minSize >= 0),
assert(maxSize <= 1),
assert(minSize <= initialSize),
assert(initialSize <= maxSize),
_currentSize = currentSize ?? ValueNotifier<double>(initialSize),
availablePixels = double.infinity,
hasDragged = hasDragged ?? false,
hasChanged = hasChanged ?? false {
}) : assert(minSize >= 0),
assert(maxSize <= 1),
assert(minSize <= initialSize),
assert(initialSize <= maxSize),
_currentSize = currentSize ?? ValueNotifier<double>(initialSize),
availablePixels = double.infinity,
hasDragged = hasDragged ?? false,
hasChanged = hasChanged ?? false {
assert(debugMaybeDispatchCreated('widgets', '_DraggableSheetExtent', this));
}
@@ -569,8 +576,9 @@ class _DraggableScrollableSheetState extends State<DraggableScrollableSheet> {
initialSize: widget.initialChildSize,
shouldCloseOnMinExtent: widget.shouldCloseOnMinExtent,
);
_scrollController =
_DraggableScrollableSheetScrollController(extent: _extent);
_scrollController = _DraggableScrollableSheetScrollController(
extent: _extent,
);
widget.controller?._attach(_scrollController);
}
@@ -621,17 +629,17 @@ class _DraggableScrollableSheetState extends State<DraggableScrollableSheet> {
valueListenable: _extent._currentSize,
builder: (BuildContext context, double currentSize, Widget? child) =>
LayoutBuilder(
builder: (BuildContext context, BoxConstraints constraints) {
_extent.availablePixels =
widget.maxChildSize * constraints.biggest.height;
final Widget sheet = FractionallySizedBox(
heightFactor: currentSize,
alignment: Alignment.bottomCenter,
child: child,
);
return widget.expand ? SizedBox.expand(child: sheet) : sheet;
},
),
builder: (BuildContext context, BoxConstraints constraints) {
_extent.availablePixels =
widget.maxChildSize * constraints.biggest.height;
final Widget sheet = FractionallySizedBox(
heightFactor: currentSize,
alignment: Alignment.bottomCenter,
child: child,
);
return widget.expand ? SizedBox.expand(child: sheet) : sheet;
},
),
child: widget.builder(context, _scrollController),
);
}
@@ -675,9 +683,11 @@ class _DraggableScrollableSheetState extends State<DraggableScrollableSheet> {
// this runs-we can't use the previous extent's available pixels as it may
// have changed when the widget was updated.
WidgetsBinding.instance.addPostFrameCallback((Duration timeStamp) {
for (int index = 0;
index < _scrollController.positions.length;
index++) {
for (
int index = 0;
index < _scrollController.positions.length;
index++
) {
final _DraggableScrollableSheetScrollPosition position =
_scrollController.positions.elementAt(index)
as _DraggableScrollableSheetScrollPosition;
@@ -688,14 +698,17 @@ class _DraggableScrollableSheetState extends State<DraggableScrollableSheet> {
}
String _snapSizeErrorMessage(int invalidIndex) {
final List<String> snapSizesWithIndicator =
widget.snapSizes!.asMap().keys.map((int index) {
final String snapSizeString = widget.snapSizes![index].toString();
if (index == invalidIndex) {
return '>>> $snapSizeString <<<';
}
return snapSizeString;
}).toList();
final List<String> snapSizesWithIndicator = widget.snapSizes!
.asMap()
.keys
.map((int index) {
final String snapSizeString = widget.snapSizes![index].toString();
if (index == invalidIndex) {
return '>>> $snapSizeString <<<';
}
return snapSizeString;
})
.toList();
return "Invalid snapSize '${widget.snapSizes![invalidIndex]}' at index $invalidIndex of:\n"
' $snapSizesWithIndicator';
}
@@ -755,11 +768,16 @@ class _DraggableScrollableSheetScrollController extends ScrollController {
// Just animate really fast.
// Avoid doing it at all if the offset is already 0.0.
if (offset != 0.0) {
animateTo(0.0,
duration: const Duration(milliseconds: 1), curve: Curves.linear);
animateTo(
0.0,
duration: const Duration(milliseconds: 1),
curve: Curves.linear,
);
}
extent.updateSize(
extent.initialSize, position.context.notificationContext!);
extent.initialSize,
position.context.notificationContext!,
);
}
@override
@@ -901,9 +919,12 @@ class _DraggableScrollableSheetScrollPosition
final AnimationController ballisticController =
AnimationController.unbounded(
debugLabel: objectRuntimeType(this, '_DraggableScrollableSheetPosition'),
vsync: context.vsync,
);
debugLabel: objectRuntimeType(
this,
'_DraggableScrollableSheetPosition',
),
vsync: context.vsync,
);
_ballisticControllers.add(ballisticController);
double lastPosition = extent.currentPixels;
@@ -916,7 +937,8 @@ class _DraggableScrollableSheetScrollPosition
// Make sure we pass along enough velocity to keep scrolling - otherwise
// we just "bounce" off the top making it look like the list doesn't
// have more to scroll.
velocity = ballisticController.velocity +
velocity =
ballisticController.velocity +
(physics.toleranceFor(this).velocity *
ballisticController.velocity.sign);
super.goBallistic(velocity);
@@ -984,8 +1006,8 @@ class DraggableScrollableActuator extends StatefulWidget {
/// some [DraggableScrollableSheet] is listening for updates, `false`
/// otherwise.
static bool reset(BuildContext context) {
final _InheritedResetNotifier? notifier =
context.dependOnInheritedWidgetOfExactType<_InheritedResetNotifier>();
final _InheritedResetNotifier? notifier = context
.dependOnInheritedWidgetOfExactType<_InheritedResetNotifier>();
return notifier?._sendReset() ?? false;
}
@@ -1040,8 +1062,10 @@ class _ResetNotifier extends ChangeNotifier {
class _InheritedResetNotifier extends InheritedNotifier<_ResetNotifier> {
/// Creates an [InheritedNotifier] that the [DraggableScrollableSheet] will
/// listen to for an indication that it should reset itself back to [DraggableScrollableSheet.initialChildSize].
const _InheritedResetNotifier(
{required super.child, required _ResetNotifier super.notifier});
const _InheritedResetNotifier({
required super.child,
required _ResetNotifier super.notifier,
});
bool _sendReset() => notifier!.sendReset();
@@ -1050,8 +1074,8 @@ class _InheritedResetNotifier extends InheritedNotifier<_ResetNotifier> {
///
/// Returns true if the notifier requested a reset, false otherwise.
static bool shouldReset(BuildContext context) {
final InheritedWidget? widget =
context.dependOnInheritedWidgetOfExactType<_InheritedResetNotifier>();
final InheritedWidget? widget = context
.dependOnInheritedWidgetOfExactType<_InheritedResetNotifier>();
if (widget == null) {
return false;
}
@@ -1076,7 +1100,8 @@ class _SnappingSimulation extends Simulation {
if (snapAnimationDuration != null &&
snapAnimationDuration.inMilliseconds > 0) {
velocity = (_pixelSnapSize - position) *
velocity =
(_pixelSnapSize - position) *
1000 /
snapAnimationDuration.inMilliseconds;
}
@@ -1126,8 +1151,9 @@ class _SnappingSimulation extends Simulation {
// non-zero, select the size in the velocity's direction. Otherwise,
// the nearest snap size.
double _getSnapSize(double initialVelocity, List<double> pixelSnapSizes) {
final int indexOfNextSize =
pixelSnapSizes.indexWhere((double size) => size >= position);
final int indexOfNextSize = pixelSnapSizes.indexWhere(
(double size) => size >= position,
);
if (indexOfNextSize == 0) {
return pixelSnapSizes.first;
}