fixed scrolling after scaling
This commit is contained in:
parent
6e53ce8cf3
commit
2740bdc597
1 changed files with 26 additions and 18 deletions
|
@ -32,6 +32,7 @@ class GridScaleGestureDetector extends StatefulWidget {
|
||||||
|
|
||||||
class _GridScaleGestureDetectorState extends State<GridScaleGestureDetector> {
|
class _GridScaleGestureDetectorState extends State<GridScaleGestureDetector> {
|
||||||
double _startExtent, _extentMin, _extentMax;
|
double _startExtent, _extentMin, _extentMax;
|
||||||
|
bool _applyingScale = false;
|
||||||
ValueNotifier<double> _scaledExtentNotifier;
|
ValueNotifier<double> _scaledExtentNotifier;
|
||||||
OverlayEntry _overlayEntry;
|
OverlayEntry _overlayEntry;
|
||||||
ThumbnailMetadata _metadata;
|
ThumbnailMetadata _metadata;
|
||||||
|
@ -47,6 +48,10 @@ class _GridScaleGestureDetectorState extends State<GridScaleGestureDetector> {
|
||||||
// horizontal drag gestures are interpreted as scaling
|
// horizontal drag gestures are interpreted as scaling
|
||||||
},
|
},
|
||||||
onScaleStart: (details) {
|
onScaleStart: (details) {
|
||||||
|
// the gesture detector wrongly detects a new scaling gesture
|
||||||
|
// when scaling ends and we apply the new extent, so we prevent this
|
||||||
|
// until we scaled and scrolled to the tile in the new grid
|
||||||
|
if (_applyingScale) return;
|
||||||
final scrollableContext = widget.scrollableKey.currentContext;
|
final scrollableContext = widget.scrollableKey.currentContext;
|
||||||
final RenderBox scrollableBox = scrollableContext.findRenderObject();
|
final RenderBox scrollableBox = scrollableContext.findRenderObject();
|
||||||
final result = BoxHitTestResult();
|
final result = BoxHitTestResult();
|
||||||
|
@ -86,12 +91,13 @@ class _GridScaleGestureDetectorState extends State<GridScaleGestureDetector> {
|
||||||
_scaledExtentNotifier.value = (_startExtent * s).clamp(_extentMin, _extentMax);
|
_scaledExtentNotifier.value = (_startExtent * s).clamp(_extentMin, _extentMax);
|
||||||
},
|
},
|
||||||
onScaleEnd: (details) {
|
onScaleEnd: (details) {
|
||||||
|
if (_scaledExtentNotifier == null) return;
|
||||||
if (_overlayEntry != null) {
|
if (_overlayEntry != null) {
|
||||||
_overlayEntry.remove();
|
_overlayEntry.remove();
|
||||||
_overlayEntry = null;
|
_overlayEntry = null;
|
||||||
}
|
}
|
||||||
if (_scaledExtentNotifier == null) return;
|
|
||||||
|
|
||||||
|
_applyingScale = true;
|
||||||
final oldExtent = tileExtentNotifier.value;
|
final oldExtent = tileExtentNotifier.value;
|
||||||
// sanitize and update grid layout if necessary
|
// sanitize and update grid layout if necessary
|
||||||
final newExtent = TileExtentManager.applyTileExtent(
|
final newExtent = TileExtentManager.applyTileExtent(
|
||||||
|
@ -101,23 +107,25 @@ class _GridScaleGestureDetectorState extends State<GridScaleGestureDetector> {
|
||||||
newExtent: _scaledExtentNotifier.value,
|
newExtent: _scaledExtentNotifier.value,
|
||||||
);
|
);
|
||||||
_scaledExtentNotifier = null;
|
_scaledExtentNotifier = null;
|
||||||
if (newExtent == oldExtent) return;
|
if (newExtent == oldExtent) {
|
||||||
|
_applyingScale = false;
|
||||||
// TODO TLAD fix scroll to specific thumbnail with custom SliverList
|
} else {
|
||||||
// scroll to show the focal point thumbnail at its new position
|
// scroll to show the focal point thumbnail at its new position
|
||||||
final viewportClosure = _renderViewport;
|
final viewportClosure = _renderViewport;
|
||||||
WidgetsBinding.instance.addPostFrameCallback((_) {
|
WidgetsBinding.instance.addPostFrameCallback((_) {
|
||||||
final scrollableContext = widget.scrollableKey.currentContext;
|
// about scrolling & offset retrieval:
|
||||||
final gridSize = (scrollableContext.findRenderObject() as RenderBox).size;
|
// `Scrollable.ensureVisible` only works on already rendered objects
|
||||||
final sectionLayout = Provider.of<SectionedListLayout>(context, listen: false);
|
// `RenderViewport.showOnScreen` can find any `RenderSliver`, but not always a `RenderMetadata`
|
||||||
final tileRect = sectionLayout.getTileRect(_metadata.entry);
|
// `RenderViewport.scrollOffsetOf` is a good alternative
|
||||||
final scrollOffset = (tileRect?.top ?? 0) - gridSize.height / 2;
|
final scrollableContext = widget.scrollableKey.currentContext;
|
||||||
viewportClosure.offset.jumpTo(scrollOffset.clamp(.0, double.infinity));
|
final gridSize = (scrollableContext.findRenderObject() as RenderBox).size;
|
||||||
// about scrolling & offset retrieval:
|
final sectionLayout = Provider.of<SectionedListLayout>(context, listen: false);
|
||||||
// `Scrollable.ensureVisible` only works on already rendered objects
|
final tileRect = sectionLayout.getTileRect(_metadata.entry);
|
||||||
// `RenderViewport.showOnScreen` can find any `RenderSliver`, but not always a `RenderMetadata`
|
final scrollOffset = (tileRect?.top ?? 0) - gridSize.height / 2;
|
||||||
// `RenderViewport.scrollOffsetOf` is a good alternative
|
viewportClosure.offset.jumpTo(max(.0, scrollOffset));
|
||||||
});
|
_applyingScale = false;
|
||||||
|
});
|
||||||
|
}
|
||||||
},
|
},
|
||||||
child: widget.child,
|
child: widget.child,
|
||||||
);
|
);
|
||||||
|
|
Loading…
Reference in a new issue