mirror of
https://github.com/HChaZZY/PiliPlus.git
synced 2025-12-20 17:16:29 +08:00
@@ -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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user